diff --git a/cipher/cipher-gcm-siv.c b/cipher/cipher-gcm-siv.c index b735d199..813cf579 100644 --- a/cipher/cipher-gcm-siv.c +++ b/cipher/cipher-gcm-siv.c @@ -1,637 +1,645 @@ /* cipher-gcm-siv.c - GCM-SIV implementation (RFC 8452) * Copyright (C) 2021 Jussi Kivilinna * * This file is part of Libgcrypt. * * Libgcrypt is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser general Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * Libgcrypt is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this program; if not, see . */ #include #include #include #include #include #include "g10lib.h" #include "cipher.h" #include "bufhelp.h" #include "./cipher-internal.h" #define GCM_SIV_NONCE_LENGTH (96 / 8) static inline void mulx_ghash (byte *a) { u64 t[2], mask; t[0] = buf_get_be64(a + 0); t[1] = buf_get_be64(a + 8); mask = -(t[1] & 1) & 0xe1; mask <<= 56; buf_put_be64(a + 8, (t[1] >> 1) ^ (t[0] << 63)); buf_put_be64(a + 0, (t[0] >> 1) ^ mask); } static inline void gcm_siv_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 int gcm_siv_check_len (u32 ctr[2]) { /* len(plaintext/aadlen) <= 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 void polyval_set_key (gcry_cipher_hd_t c, const byte *auth_key) { cipher_block_bswap (c->u_mode.gcm.u_ghash_key.key, auth_key, GCRY_SIV_BLOCK_LEN); mulx_ghash (c->u_mode.gcm.u_ghash_key.key); _gcry_cipher_gcm_setupM (c); } static void do_polyval_buf(gcry_cipher_hd_t c, byte *hash, const byte *buf, size_t buflen, int do_padding) { unsigned int blocksize = GCRY_SIV_BLOCK_LEN; unsigned int unused = c->u_mode.gcm.mac_unused; ghash_fn_t ghash_fn = c->u_mode.gcm.ghash_fn; byte tmp_blocks[16][GCRY_SIV_BLOCK_LEN]; size_t nblocks, n; unsigned int burn = 0, nburn; unsigned int num_blks_used = 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. */ cipher_block_bswap (c->u_mode.gcm.macbuf, c->u_mode.gcm.macbuf, blocksize); nburn = ghash_fn (c, hash, c->u_mode.gcm.macbuf, 1); burn = nburn > burn ? nburn : burn; unused = 0; } nblocks = buflen / blocksize; while (nblocks) { for (n = 0; n < (nblocks > 16 ? 16 : nblocks); n++) cipher_block_bswap (tmp_blocks[n], buf + n * blocksize, blocksize); num_blks_used = n > num_blks_used ? n : num_blks_used; nburn = ghash_fn (c, hash, tmp_blocks[0], n); burn = nburn > burn ? nburn : burn; buf += n * blocksize; buflen -= n * blocksize; nblocks -= n; } } while (buflen > 0); c->u_mode.gcm.mac_unused = unused; if (num_blks_used) wipememory (tmp_blocks, num_blks_used * blocksize); if (burn) _gcry_burn_stack (burn); } static void do_ctr_le32 (gcry_cipher_hd_t c, byte *outbuf, const byte *inbuf, size_t inbuflen) { gcry_cipher_encrypt_t enc_fn = c->spec->encrypt; unsigned char tmp[GCRY_SIV_BLOCK_LEN]; unsigned int burn = 0, nburn; - size_t n; + size_t nblocks; if (inbuflen == 0) return; - n = GCRY_SIV_BLOCK_LEN; + /* Use a bulk method if available. */ + nblocks = inbuflen / GCRY_SIV_BLOCK_LEN; + if (nblocks && c->bulk.ctr32le_enc) + { + c->bulk.ctr32le_enc (c->context.c, c->u_ctr.ctr, outbuf, inbuf, nblocks); + inbuf += nblocks * GCRY_SIV_BLOCK_LEN; + outbuf += nblocks * GCRY_SIV_BLOCK_LEN; + inbuflen -= nblocks * GCRY_SIV_BLOCK_LEN; + } + do { nburn = enc_fn (c->context.c, tmp, c->u_ctr.ctr); burn = nburn > burn ? nburn : burn; buf_put_le32(c->u_ctr.ctr, buf_get_le32(c->u_ctr.ctr) + 1); if (inbuflen < GCRY_SIV_BLOCK_LEN) break; cipher_block_xor(outbuf, inbuf, tmp, GCRY_SIV_BLOCK_LEN); - inbuflen -= n; - outbuf += n; - inbuf += n; + inbuflen -= GCRY_SIV_BLOCK_LEN; + outbuf += GCRY_SIV_BLOCK_LEN; + inbuf += GCRY_SIV_BLOCK_LEN; } while (inbuflen); if (inbuflen) { - n = inbuflen; buf_xor(outbuf, inbuf, tmp, inbuflen); - inbuflen -= n; - outbuf += n; - inbuf += n; + outbuf += inbuflen; + inbuf += inbuflen; + inbuflen -= inbuflen; } wipememory (tmp, sizeof(tmp)); if (burn > 0) _gcry_burn_stack (burn + 4 * sizeof(void *)); } static int gcm_siv_selftest (gcry_cipher_hd_t c) { static const byte in1[GCRY_SIV_BLOCK_LEN] = "\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"; static const byte out1[GCRY_SIV_BLOCK_LEN] = "\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"; static const byte in2[GCRY_SIV_BLOCK_LEN] = "\x9c\x98\xc0\x4d\xf9\x38\x7d\xed\x82\x81\x75\xa9\x2b\xa6\x52\xd8"; static const byte out2[GCRY_SIV_BLOCK_LEN] = "\x4e\x4c\x60\x26\xfc\x9c\x3e\xf6\xc1\x40\xba\xd4\x95\xd3\x29\x6c"; static const byte polyval_key[GCRY_SIV_BLOCK_LEN] = "\x25\x62\x93\x47\x58\x92\x42\x76\x1d\x31\xf8\x26\xba\x4b\x75\x7b"; static const byte ghash_key[GCRY_SIV_BLOCK_LEN] = "\xdc\xba\xa5\xdd\x13\x7c\x18\x8e\xbb\x21\x49\x2c\x23\xc9\xb1\x12"; static const byte polyval_data[GCRY_SIV_BLOCK_LEN * 2] = "\x4f\x4f\x95\x66\x8c\x83\xdf\xb6\x40\x17\x62\xbb\x2d\x01\xa2\x62" "\xd1\xa2\x4d\xdd\x27\x21\xd0\x06\xbb\xe4\x5f\x20\xd3\xc9\xf3\x62"; static const byte polyval_tag[GCRY_SIV_BLOCK_LEN] = "\xf7\xa3\xb4\x7b\x84\x61\x19\xfa\xe5\xb7\x86\x6c\xf5\xe5\xb7\x7e"; byte tmp[GCRY_SIV_BLOCK_LEN]; /* Test mulx_ghash */ memcpy (tmp, in1, GCRY_SIV_BLOCK_LEN); mulx_ghash (tmp); if (memcmp (tmp, out1, GCRY_SIV_BLOCK_LEN) != 0) return -1; memcpy (tmp, in2, GCRY_SIV_BLOCK_LEN); mulx_ghash (tmp); if (memcmp (tmp, out2, GCRY_SIV_BLOCK_LEN) != 0) return -1; /* Test GHASH key generation */ memcpy (tmp, polyval_key, GCRY_SIV_BLOCK_LEN); cipher_block_bswap (tmp, tmp, GCRY_SIV_BLOCK_LEN); mulx_ghash (tmp); if (memcmp (tmp, ghash_key, GCRY_SIV_BLOCK_LEN) != 0) return -1; /* Test POLYVAL */ memset (&c->u_mode.gcm, 0, sizeof(c->u_mode.gcm)); polyval_set_key (c, polyval_key); memset (&tmp, 0, sizeof(tmp)); do_polyval_buf (c, tmp, polyval_data, GCRY_SIV_BLOCK_LEN * 2, 1); cipher_block_bswap (tmp, tmp, GCRY_SIV_BLOCK_LEN); if (memcmp (tmp, polyval_tag, GCRY_SIV_BLOCK_LEN) != 0) return -1; return 0; } gcry_err_code_t _gcry_cipher_gcm_siv_setkey (gcry_cipher_hd_t c, unsigned int keylen) { static int done; if (keylen != 16 && keylen != 32) return GPG_ERR_INV_KEYLEN; if (!done) { if (gcm_siv_selftest (c)) return GPG_ERR_SELFTEST_FAILED; done = 1; } c->marks.iv = 0; c->marks.tag = 0; memset (&c->u_mode.gcm, 0, sizeof(c->u_mode.gcm)); c->u_mode.gcm.siv_keylen = keylen; return 0; } gcry_err_code_t _gcry_cipher_gcm_siv_set_nonce (gcry_cipher_hd_t c, const byte *iv, size_t ivlen) { byte auth_key[GCRY_SIV_BLOCK_LEN]; byte tmp_in[GCRY_SIV_BLOCK_LEN]; byte tmp[GCRY_SIV_BLOCK_LEN]; byte enc_key[32]; gcry_err_code_t err; if (c->spec->blocksize != GCRY_SIV_BLOCK_LEN) return GPG_ERR_CIPHER_ALGO; if (ivlen != GCM_SIV_NONCE_LENGTH) return GPG_ERR_INV_ARG; if (c->u_mode.gcm.siv_keylen == 0) return GPG_ERR_INV_STATE; if (c->marks.iv) { /* If nonce is already set, use cipher_reset or setkey first to reset * cipher state. */ return GPG_ERR_INV_STATE; } 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, sizeof(c->u_mode.gcm.u_tag.tag)); c->u_mode.gcm.datalen_over_limits = 0; c->u_mode.gcm.ghash_data_finalized = 0; c->u_mode.gcm.ghash_aad_finalized = 0; memset (c->u_iv.iv, 0, GCRY_SIV_BLOCK_LEN); memcpy (c->u_iv.iv, iv, ivlen); memcpy (tmp_in + 4, iv, ivlen); /* Derive message authentication key */ buf_put_le32(tmp_in, 0); c->spec->encrypt (&c->context.c, tmp, tmp_in); memcpy (auth_key + 0, tmp, 8); buf_put_le32(tmp_in, 1); c->spec->encrypt (&c->context.c, tmp, tmp_in); memcpy (auth_key + 8, tmp, 8); polyval_set_key (c, auth_key); wipememory (auth_key, sizeof(auth_key)); /* Derive message encryption key */ buf_put_le32(tmp_in, 2); c->spec->encrypt (&c->context.c, tmp, tmp_in); memcpy (enc_key + 0, tmp, 8); buf_put_le32(tmp_in, 3); c->spec->encrypt (&c->context.c, tmp, tmp_in); memcpy (enc_key + 8, tmp, 8); if (c->u_mode.gcm.siv_keylen >= 24) { buf_put_le32(tmp_in, 4); c->spec->encrypt (&c->context.c, tmp, tmp_in); memcpy (enc_key + 16, tmp, 8); } if (c->u_mode.gcm.siv_keylen >= 32) { buf_put_le32(tmp_in, 5); c->spec->encrypt (&c->context.c, tmp, tmp_in); memcpy (enc_key + 24, tmp, 8); } wipememory (tmp, sizeof(tmp)); wipememory (tmp_in, sizeof(tmp_in)); err = c->spec->setkey (&c->context.c, enc_key, c->u_mode.gcm.siv_keylen, &c->bulk); wipememory (enc_key, sizeof(enc_key)); if (err) return err; c->marks.iv = 1; return 0; } gcry_err_code_t _gcry_cipher_gcm_siv_authenticate (gcry_cipher_hd_t c, const byte *aadbuf, size_t aadbuflen) { if (c->spec->blocksize != GCRY_SIV_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->marks.iv || 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; gcm_siv_bytecounter_add (c->u_mode.gcm.aadlen, aadbuflen); if (!gcm_siv_check_len (c->u_mode.gcm.aadlen)) { c->u_mode.gcm.datalen_over_limits = 1; return GPG_ERR_INV_LENGTH; } do_polyval_buf (c, c->u_mode.gcm.u_tag.tag, aadbuf, aadbuflen, 0); return 0; } gcry_err_code_t _gcry_cipher_gcm_siv_encrypt (gcry_cipher_hd_t c, byte *outbuf, size_t outbuflen, const byte *inbuf, size_t inbuflen) { u32 bitlengths[2][2]; if (c->spec->blocksize != GCRY_SIV_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->marks.iv || c->u_mode.gcm.ghash_data_finalized || !c->u_mode.gcm.ghash_fn) return GPG_ERR_INV_STATE; if (!c->u_mode.gcm.ghash_aad_finalized) { /* Start of encryption marks end of AAD stream. */ do_polyval_buf(c, c->u_mode.gcm.u_tag.tag, NULL, 0, 1); c->u_mode.gcm.ghash_aad_finalized = 1; } gcm_siv_bytecounter_add (c->u_mode.gcm.datalen, inbuflen); if (!gcm_siv_check_len (c->u_mode.gcm.datalen)) { c->u_mode.gcm.datalen_over_limits = 1; return GPG_ERR_INV_LENGTH; } /* Plaintext and padding to POLYVAL. */ do_polyval_buf (c, c->u_mode.gcm.u_tag.tag, inbuf, inbuflen, 1); c->u_mode.gcm.ghash_data_finalized = 1; /* aad length */ bitlengths[0][0] = le_bswap32(c->u_mode.gcm.aadlen[0] << 3); bitlengths[0][1] = le_bswap32((c->u_mode.gcm.aadlen[0] >> 29) | (c->u_mode.gcm.aadlen[1] << 3)); /* data length */ bitlengths[1][0] = le_bswap32(c->u_mode.gcm.datalen[0] << 3); bitlengths[1][1] = le_bswap32((c->u_mode.gcm.datalen[0] >> 29) | (c->u_mode.gcm.datalen[1] << 3)); /* Length block to POLYVAL. */ do_polyval_buf(c, c->u_mode.gcm.u_tag.tag, (byte *)bitlengths, GCRY_SIV_BLOCK_LEN, 1); wipememory (bitlengths, sizeof(bitlengths)); /* Prepare tag and counter. */ cipher_block_bswap (c->u_mode.gcm.u_tag.tag, c->u_mode.gcm.u_tag.tag, GCRY_SIV_BLOCK_LEN); cipher_block_xor (c->u_mode.gcm.tagiv, c->u_iv.iv, c->u_mode.gcm.u_tag.tag, GCRY_SIV_BLOCK_LEN); c->u_mode.gcm.tagiv[GCRY_SIV_BLOCK_LEN - 1] &= 0x7f; c->spec->encrypt (&c->context.c, c->u_mode.gcm.tagiv, c->u_mode.gcm.tagiv); c->marks.tag = 1; memcpy (c->u_ctr.ctr, c->u_mode.gcm.tagiv, GCRY_SIV_BLOCK_LEN); c->u_ctr.ctr[GCRY_SIV_BLOCK_LEN - 1] |= 0x80; /* Encrypt data */ do_ctr_le32 (c, outbuf, inbuf, inbuflen); return 0; } gcry_err_code_t _gcry_cipher_gcm_siv_set_decryption_tag (gcry_cipher_hd_t c, const byte *tag, size_t taglen) { if (taglen != GCRY_SIV_BLOCK_LEN) return GPG_ERR_INV_ARG; if (c->spec->blocksize != GCRY_SIV_BLOCK_LEN) return GPG_ERR_CIPHER_ALGO; if (c->marks.tag) return GPG_ERR_INV_STATE; memcpy (c->u_mode.gcm.tagiv, tag, GCRY_SIV_BLOCK_LEN); c->marks.tag = 1; return 0; } gcry_err_code_t _gcry_cipher_gcm_siv_decrypt (gcry_cipher_hd_t c, byte *outbuf, size_t outbuflen, const byte *inbuf, size_t inbuflen) { byte expected_tag[GCRY_SIV_BLOCK_LEN]; u32 bitlengths[2][2]; gcry_err_code_t rc = 0; if (c->spec->blocksize != GCRY_SIV_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->marks.iv || c->u_mode.gcm.ghash_data_finalized || !c->u_mode.gcm.ghash_fn) return GPG_ERR_INV_STATE; if (!c->u_mode.gcm.ghash_aad_finalized) { /* Start of encryption marks end of AAD stream. */ do_polyval_buf(c, c->u_mode.gcm.u_tag.tag, NULL, 0, 1); c->u_mode.gcm.ghash_aad_finalized = 1; } gcm_siv_bytecounter_add (c->u_mode.gcm.datalen, inbuflen); if (!gcm_siv_check_len (c->u_mode.gcm.datalen)) { c->u_mode.gcm.datalen_over_limits = 1; return GPG_ERR_INV_LENGTH; } /* Prepare counter. */ memcpy (c->u_ctr.ctr, c->u_mode.gcm.tagiv, GCRY_SIV_BLOCK_LEN); c->u_ctr.ctr[GCRY_SIV_BLOCK_LEN - 1] |= 0x80; /* Decrypt data. */ do_ctr_le32 (c, outbuf, inbuf, inbuflen); /* Plaintext and padding to POLYVAL. */ do_polyval_buf (c, c->u_mode.gcm.u_tag.tag, outbuf, inbuflen, 1); c->u_mode.gcm.ghash_data_finalized = 1; /* aad length */ bitlengths[0][0] = le_bswap32(c->u_mode.gcm.aadlen[0] << 3); bitlengths[0][1] = le_bswap32((c->u_mode.gcm.aadlen[0] >> 29) | (c->u_mode.gcm.aadlen[1] << 3)); /* data length */ bitlengths[1][0] = le_bswap32(c->u_mode.gcm.datalen[0] << 3); bitlengths[1][1] = le_bswap32((c->u_mode.gcm.datalen[0] >> 29) | (c->u_mode.gcm.datalen[1] << 3)); /* Length block to POLYVAL. */ do_polyval_buf(c, c->u_mode.gcm.u_tag.tag, (byte *)bitlengths, GCRY_SIV_BLOCK_LEN, 1); wipememory (bitlengths, sizeof(bitlengths)); /* Prepare tag. */ cipher_block_bswap (c->u_mode.gcm.u_tag.tag, c->u_mode.gcm.u_tag.tag, GCRY_SIV_BLOCK_LEN); cipher_block_xor (expected_tag, c->u_iv.iv, c->u_mode.gcm.u_tag.tag, GCRY_SIV_BLOCK_LEN); expected_tag[GCRY_SIV_BLOCK_LEN - 1] &= 0x7f; c->spec->encrypt (&c->context.c, expected_tag, expected_tag); if (!buf_eq_const(c->u_mode.gcm.tagiv, expected_tag, GCRY_SIV_BLOCK_LEN)) { wipememory (outbuf, inbuflen); rc = GPG_ERR_CHECKSUM; } wipememory (expected_tag, sizeof(expected_tag)); return rc; } static gcry_err_code_t _gcry_cipher_gcm_siv_tag (gcry_cipher_hd_t c, byte * outbuf, size_t outbuflen, int check) { gcry_err_code_t err; if (!c->marks.tag) { if (!c->u_mode.gcm.ghash_fn) return GPG_ERR_INV_STATE; if (!c->marks.tag) { /* Finalize GCM-SIV with zero-length plaintext. */ err = _gcry_cipher_gcm_siv_encrypt (c, NULL, 0, NULL, 0); if (err != 0) return err; } } if (c->u_mode.gcm.datalen_over_limits) return GPG_ERR_INV_LENGTH; if (!c->u_mode.gcm.ghash_data_finalized) return GPG_ERR_INV_STATE; if (!c->marks.tag) return GPG_ERR_INV_STATE; if (!check) { if (outbuflen > GCRY_SIV_BLOCK_LEN) outbuflen = GCRY_SIV_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.tagiv, outbuflen); } else { /* OUTBUFLEN gives the length of the user supplied tag in OUTBUF * and thus we need to compare its length first. */ if (outbuflen != GCRY_SIV_BLOCK_LEN || !buf_eq_const (outbuf, c->u_mode.gcm.tagiv, outbuflen)) return GPG_ERR_CHECKSUM; } return 0; } gcry_err_code_t _gcry_cipher_gcm_siv_get_tag (gcry_cipher_hd_t c, unsigned char *outtag, size_t taglen) { return _gcry_cipher_gcm_siv_tag (c, outtag, taglen, 0); } gcry_err_code_t _gcry_cipher_gcm_siv_check_tag (gcry_cipher_hd_t c, const unsigned char *intag, size_t taglen) { return _gcry_cipher_gcm_siv_tag (c, (unsigned char *)intag, taglen, 1); } diff --git a/cipher/cipher-internal.h b/cipher/cipher-internal.h index 8b04cff7..0bc85b1a 100644 --- a/cipher/cipher-internal.h +++ b/cipher/cipher-internal.h @@ -1,932 +1,934 @@ /* cipher-internal.h - Internal defs for cipher.c * Copyright (C) 2011 Free Software Foundation, Inc. * * This file is part of Libgcrypt. * * Libgcrypt is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser general Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * Libgcrypt is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this program; if not, see . */ #ifndef G10_CIPHER_INTERNAL_H #define G10_CIPHER_INTERNAL_H #include "./poly1305-internal.h" /* The maximum supported size of a block in bytes. */ #define MAX_BLOCKSIZE 16 /* The length for an OCB block. Although OCB supports any block length it does not make sense to use a 64 bit blocklen (and cipher) because this reduces the security margin to an unacceptable state. Thus we require a cipher with 128 bit blocklength. */ #define OCB_BLOCK_LEN (128/8) /* The size of the pre-computed L table for OCB. This takes the same size as the table used for GCM and thus we don't save anything by not using such a table. */ #define OCB_L_TABLE_SIZE 16 /* Check the above constants. */ #if OCB_BLOCK_LEN > MAX_BLOCKSIZE # error OCB_BLOCKLEN > MAX_BLOCKSIZE #endif /* Magic values for the context structure. */ #define CTX_MAGIC_NORMAL 0x24091964 #define CTX_MAGIC_SECURE 0x46919042 /* Try to use 16 byte aligned cipher context for better performance. We use the aligned attribute, thus it is only possible to implement this with gcc. */ #undef NEED_16BYTE_ALIGNED_CONTEXT #ifdef HAVE_GCC_ATTRIBUTE_ALIGNED # define NEED_16BYTE_ALIGNED_CONTEXT 1 #endif /* Undef this symbol to trade GCM speed for 256 bytes of memory per context */ #define GCM_USE_TABLES 1 /* GCM_USE_INTEL_PCLMUL indicates whether to compile GCM with Intel PCLMUL code. */ #undef GCM_USE_INTEL_PCLMUL #if defined(ENABLE_PCLMUL_SUPPORT) && defined(GCM_USE_TABLES) # if ((defined(__i386__) && SIZEOF_UNSIGNED_LONG == 4) || defined(__x86_64__)) # if __GNUC__ >= 4 # define GCM_USE_INTEL_PCLMUL 1 # endif # endif #endif /* GCM_USE_INTEL_PCLMUL */ /* GCM_USE_ARM_PMULL indicates whether to compile GCM with ARMv8 PMULL code. */ #undef GCM_USE_ARM_PMULL #if defined(ENABLE_ARM_CRYPTO_SUPPORT) && defined(GCM_USE_TABLES) # if defined(HAVE_ARM_ARCH_V6) && defined(__ARMEL__) \ && defined(HAVE_COMPATIBLE_GCC_ARM_PLATFORM_AS) \ && defined(HAVE_GCC_INLINE_ASM_AARCH32_CRYPTO) # define GCM_USE_ARM_PMULL 1 # elif defined(__AARCH64EL__) && \ defined(HAVE_COMPATIBLE_GCC_AARCH64_PLATFORM_AS) && \ defined(HAVE_GCC_INLINE_ASM_AARCH64_CRYPTO) # define GCM_USE_ARM_PMULL 1 # endif #endif /* GCM_USE_ARM_PMULL */ /* 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 */ /* GCM_USE_PPC_VPMSUM indicates whether to compile GCM with PPC Power 8 * polynomial multiplication instruction. */ #undef GCM_USE_PPC_VPMSUM #if defined(GCM_USE_TABLES) #if defined(ENABLE_PPC_CRYPTO_SUPPORT) && defined(__powerpc64__) && \ defined(HAVE_COMPATIBLE_CC_PPC_ALTIVEC) && \ defined(HAVE_GCC_INLINE_ASM_PPC_ALTIVEC) && __GNUC__ >= 4 # define GCM_USE_PPC_VPMSUM 1 # define NEED_16BYTE_ALIGNED_CONTEXT 1 /* this also aligns gcm_table */ #endif #endif /* GCM_USE_PPC_VPMSUM */ 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); + void (*ctr32le_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 and GCM-SIV 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; /* 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 /* GHASH implementation in use. */ ghash_fn_t ghash_fn; /* Key length used for GCM-SIV key generating key. */ unsigned int siv_keylen; } 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; /* Mode specific storage for SIV mode. */ struct { /* Tag used for decryption. */ unsigned char dec_tag[GCRY_SIV_BLOCK_LEN]; /* S2V state. */ unsigned char s2v_d[GCRY_SIV_BLOCK_LEN]; /* Number of AAD elements processed. */ unsigned int aad_count:8; /* Flags for SIV state. */ unsigned int dec_tag_set:1; /* --- Following members are not cleared in gcry_cipher_reset --- */ /* S2V CMAC state. */ gcry_cmac_context_t s2v_cmac; unsigned char s2v_zero_block[GCRY_SIV_BLOCK_LEN]; /* Pointer to CTR cipher context, allocated after actual * cipher context. */ char *ctr_context; } siv; } 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_ctx /* */ (gcry_cipher_hd_t c, unsigned char *outbuf, size_t outbuflen, const unsigned char *inbuf, size_t inbuflen, void *algo_context); 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); void _gcry_cipher_gcm_setupM /* */ (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); /*-- cipher-siv.c --*/ gcry_err_code_t _gcry_cipher_siv_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_siv_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_siv_set_nonce /* */ (gcry_cipher_hd_t c, const unsigned char *nonce, size_t noncelen); gcry_err_code_t _gcry_cipher_siv_authenticate /* */ (gcry_cipher_hd_t c, const unsigned char *abuf, size_t abuflen); gcry_err_code_t _gcry_cipher_siv_set_decryption_tag /* */ (gcry_cipher_hd_t c, const byte *tag, size_t taglen); gcry_err_code_t _gcry_cipher_siv_get_tag /* */ (gcry_cipher_hd_t c, unsigned char *outtag, size_t taglen); gcry_err_code_t _gcry_cipher_siv_check_tag /* */ (gcry_cipher_hd_t c, const unsigned char *intag, size_t taglen); gcry_err_code_t _gcry_cipher_siv_setkey /* */ (gcry_cipher_hd_t c, const unsigned char *ctrkey, size_t ctrkeylen); /*-- cipher-gcm-siv.c --*/ gcry_err_code_t _gcry_cipher_gcm_siv_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_siv_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_siv_set_nonce /* */ (gcry_cipher_hd_t c, const unsigned char *nonce, size_t noncelen); gcry_err_code_t _gcry_cipher_gcm_siv_authenticate /* */ (gcry_cipher_hd_t c, const unsigned char *abuf, size_t abuflen); gcry_err_code_t _gcry_cipher_gcm_siv_set_decryption_tag /* */ (gcry_cipher_hd_t c, const byte *tag, size_t taglen); gcry_err_code_t _gcry_cipher_gcm_siv_get_tag /* */ (gcry_cipher_hd_t c, unsigned char *outtag, size_t taglen); gcry_err_code_t _gcry_cipher_gcm_siv_check_tag /* */ (gcry_cipher_hd_t c, const unsigned char *intag, size_t taglen); gcry_err_code_t _gcry_cipher_gcm_siv_setkey /* */ (gcry_cipher_hd_t c, unsigned int keylen); /* 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 byte-swapping. */ static inline void cipher_block_bswap (void *_dst_bswap, const void *_src_bswap, size_t blocksize) { byte *dst_bswap = _dst_bswap; const byte *src_bswap = _src_bswap; u64 t[2]; if (blocksize == 8) { buf_put_le64(dst_bswap, buf_get_be64(src_bswap)); } else { t[0] = buf_get_be64(src_bswap + 0); t[1] = buf_get_be64(src_bswap + 8); buf_put_le64(dst_bswap + 8, t[0]); buf_put_le64(dst_bswap + 0, t[1]); } } /* Optimized function for combined cipher block xoring and copying. Used by mainly CFB mode decryption. */ static inline void cipher_block_xor_n_copy(void *_dst_xor, void *_srcdst_cpy, const void *_src, size_t blocksize) { cipher_block_xor_n_copy_2(_dst_xor, _src, _srcdst_cpy, _src, blocksize); } #endif /*G10_CIPHER_INTERNAL_H*/ diff --git a/cipher/rijndael-aesni.c b/cipher/rijndael-aesni.c index 9dde0489..34a4a447 100644 --- a/cipher/rijndael-aesni.c +++ b/cipher/rijndael-aesni.c @@ -1,4559 +1,4751 @@ /* AES-NI accelerated AES for Libgcrypt * Copyright (C) 2000, 2001, 2002, 2003, 2007, * 2008, 2011, 2012 Free Software Foundation, Inc. * * This file is part of Libgcrypt. * * Libgcrypt is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * Libgcrypt is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this program; if not, see . */ #include #include #include #include /* for memcmp() */ #include "types.h" /* for byte and u32 typedefs */ #include "g10lib.h" #include "cipher.h" #include "bufhelp.h" #include "cipher-selftest.h" #include "rijndael-internal.h" #include "./cipher-internal.h" #ifdef USE_AESNI #if _GCRY_GCC_VERSION >= 40400 /* 4.4 */ /* Prevent compiler from issuing SSE instructions between asm blocks. */ # pragma GCC target("no-sse") #endif #if __clang__ # pragma clang attribute push (__attribute__((target("no-sse"))), apply_to = function) #endif #define ALWAYS_INLINE inline __attribute__((always_inline)) #define NO_INLINE __attribute__((noinline)) #define NO_INSTRUMENT_FUNCTION __attribute__((no_instrument_function)) #define ASM_FUNC_ATTR NO_INSTRUMENT_FUNCTION #define ASM_FUNC_ATTR_INLINE ASM_FUNC_ATTR ALWAYS_INLINE #define ASM_FUNC_ATTR_NOINLINE ASM_FUNC_ATTR NO_INLINE typedef struct u128_s { u32 a, b, c, d; } __attribute__((packed, aligned(1), may_alias)) u128_t; /* Copy of ocb_get_l needed here as GCC is unable to inline ocb_get_l because of 'pragma target'. */ static ASM_FUNC_ATTR_INLINE const unsigned char * aes_ocb_get_l (gcry_cipher_hd_t c, u64 n) { unsigned long ntz; /* Assumes that N != 0. */ asm ("rep;bsfl %k[low], %k[ntz]\n\t" : [ntz] "=r" (ntz) : [low] "r" ((unsigned long)n) : "cc"); return c->u_mode.ocb.L[ntz]; } /* Two macros to be called prior and after the use of AESNI instructions. There should be no external function calls between the use of these macros. There purpose is to make sure that the SSE regsiters are cleared and won't reveal any information about the key or the data. */ #ifdef __WIN64__ /* XMM6-XMM15 are callee-saved registers on WIN64. */ # define aesni_prepare_2_7_variable char win64tmp[16 * 2] # define aesni_prepare_8_15_variable char win64tmp8_15[16 * 8] # define aesni_prepare() do { } while (0) # define aesni_prepare_2_7() \ do { asm volatile ("movdqu %%xmm6, %0\n\t" \ "movdqu %%xmm7, %1\n\t" \ : "=m" (*win64tmp), "=m" (*(win64tmp+16)) \ : \ : "memory"); \ } while (0) # define aesni_prepare_8_15() \ do { asm volatile ("movdqu %%xmm8, 0*16(%0)\n\t" \ "movdqu %%xmm9, 1*16(%0)\n\t" \ "movdqu %%xmm10, 2*16(%0)\n\t" \ "movdqu %%xmm11, 3*16(%0)\n\t" \ "movdqu %%xmm12, 4*16(%0)\n\t" \ "movdqu %%xmm13, 5*16(%0)\n\t" \ "movdqu %%xmm14, 6*16(%0)\n\t" \ "movdqu %%xmm15, 7*16(%0)\n\t" \ : \ : "r" (win64tmp8_15) \ : "memory"); \ } while (0) # define aesni_cleanup() \ do { asm volatile ("pxor %%xmm0, %%xmm0\n\t" \ "pxor %%xmm1, %%xmm1\n" :: ); \ } while (0) # define aesni_cleanup_2_7() \ do { asm volatile ("movdqu %0, %%xmm6\n\t" \ "movdqu %1, %%xmm7\n\t" \ "pxor %%xmm2, %%xmm2\n" \ "pxor %%xmm3, %%xmm3\n" \ "pxor %%xmm4, %%xmm4\n" \ "pxor %%xmm5, %%xmm5\n" \ : \ : "m" (*win64tmp), "m" (*(win64tmp+16)) \ : "memory"); \ } while (0) # define aesni_cleanup_8_15() \ do { asm volatile ("movdqu 0*16(%0), %%xmm8\n\t" \ "movdqu 1*16(%0), %%xmm9\n\t" \ "movdqu 2*16(%0), %%xmm10\n\t" \ "movdqu 3*16(%0), %%xmm11\n\t" \ "movdqu 4*16(%0), %%xmm12\n\t" \ "movdqu 5*16(%0), %%xmm13\n\t" \ "movdqu 6*16(%0), %%xmm14\n\t" \ "movdqu 7*16(%0), %%xmm15\n\t" \ : \ : "r" (win64tmp8_15) \ : "memory"); \ } while (0) #else # define aesni_prepare_2_7_variable # define aesni_prepare() do { } while (0) # define aesni_prepare_2_7() do { } while (0) # define aesni_cleanup() \ do { asm volatile ("pxor %%xmm0, %%xmm0\n\t" \ "pxor %%xmm1, %%xmm1\n" :: ); \ } while (0) # define aesni_cleanup_2_7() \ do { asm volatile ("pxor %%xmm7, %%xmm7\n\t" \ "pxor %%xmm2, %%xmm2\n\t" \ "pxor %%xmm3, %%xmm3\n" \ "pxor %%xmm4, %%xmm4\n" \ "pxor %%xmm5, %%xmm5\n" \ "pxor %%xmm6, %%xmm6\n":: ); \ } while (0) # ifdef __x86_64__ # define aesni_prepare_8_15_variable # define aesni_prepare_8_15() do { } while (0) # define aesni_cleanup_8_15() \ do { asm volatile ("pxor %%xmm8, %%xmm8\n" \ "pxor %%xmm9, %%xmm9\n" \ "pxor %%xmm10, %%xmm10\n" \ "pxor %%xmm11, %%xmm11\n" \ "pxor %%xmm12, %%xmm12\n" \ "pxor %%xmm13, %%xmm13\n" \ "pxor %%xmm14, %%xmm14\n" \ "pxor %%xmm15, %%xmm15\n":: ); \ } while (0) # endif #endif void ASM_FUNC_ATTR _gcry_aes_aesni_do_setkey (RIJNDAEL_context *ctx, const byte *key) { aesni_prepare_2_7_variable; aesni_prepare(); aesni_prepare_2_7(); if (ctx->rounds < 12) { /* 128-bit key */ #define AESKEYGENASSIST_xmm1_xmm2(imm8) \ ".byte 0x66, 0x0f, 0x3a, 0xdf, 0xd1, " #imm8 " \n\t" #define AESKEY_EXPAND128 \ "pshufd $0xff, %%xmm2, %%xmm2\n\t" \ "movdqa %%xmm1, %%xmm3\n\t" \ "pslldq $4, %%xmm3\n\t" \ "pxor %%xmm3, %%xmm1\n\t" \ "pslldq $4, %%xmm3\n\t" \ "pxor %%xmm3, %%xmm1\n\t" \ "pslldq $4, %%xmm3\n\t" \ "pxor %%xmm3, %%xmm2\n\t" \ "pxor %%xmm2, %%xmm1\n\t" asm volatile ("movdqu (%[key]), %%xmm1\n\t" /* xmm1 := key */ "movdqa %%xmm1, (%[ksch])\n\t" /* ksch[0] := xmm1 */ AESKEYGENASSIST_xmm1_xmm2(0x01) AESKEY_EXPAND128 "movdqa %%xmm1, 0x10(%[ksch])\n\t" /* ksch[1] := xmm1 */ AESKEYGENASSIST_xmm1_xmm2(0x02) AESKEY_EXPAND128 "movdqa %%xmm1, 0x20(%[ksch])\n\t" /* ksch[2] := xmm1 */ AESKEYGENASSIST_xmm1_xmm2(0x04) AESKEY_EXPAND128 "movdqa %%xmm1, 0x30(%[ksch])\n\t" /* ksch[3] := xmm1 */ AESKEYGENASSIST_xmm1_xmm2(0x08) AESKEY_EXPAND128 "movdqa %%xmm1, 0x40(%[ksch])\n\t" /* ksch[4] := xmm1 */ AESKEYGENASSIST_xmm1_xmm2(0x10) AESKEY_EXPAND128 "movdqa %%xmm1, 0x50(%[ksch])\n\t" /* ksch[5] := xmm1 */ AESKEYGENASSIST_xmm1_xmm2(0x20) AESKEY_EXPAND128 "movdqa %%xmm1, 0x60(%[ksch])\n\t" /* ksch[6] := xmm1 */ AESKEYGENASSIST_xmm1_xmm2(0x40) AESKEY_EXPAND128 "movdqa %%xmm1, 0x70(%[ksch])\n\t" /* ksch[7] := xmm1 */ AESKEYGENASSIST_xmm1_xmm2(0x80) AESKEY_EXPAND128 "movdqa %%xmm1, 0x80(%[ksch])\n\t" /* ksch[8] := xmm1 */ AESKEYGENASSIST_xmm1_xmm2(0x1b) AESKEY_EXPAND128 "movdqa %%xmm1, 0x90(%[ksch])\n\t" /* ksch[9] := xmm1 */ AESKEYGENASSIST_xmm1_xmm2(0x36) AESKEY_EXPAND128 "movdqa %%xmm1, 0xa0(%[ksch])\n\t" /* ksch[10] := xmm1 */ : : [key] "r" (key), [ksch] "r" (ctx->keyschenc) : "cc", "memory" ); #undef AESKEYGENASSIST_xmm1_xmm2 #undef AESKEY_EXPAND128 } else if (ctx->rounds == 12) { /* 192-bit key */ #define AESKEYGENASSIST_xmm3_xmm2(imm8) \ ".byte 0x66, 0x0f, 0x3a, 0xdf, 0xd3, " #imm8 " \n\t" #define AESKEY_EXPAND192 \ "pshufd $0x55, %%xmm2, %%xmm2\n\t" \ "movdqu %%xmm1, %%xmm4\n\t" \ "pslldq $4, %%xmm4\n\t" \ "pxor %%xmm4, %%xmm1\n\t" \ "pslldq $4, %%xmm4\n\t" \ "pxor %%xmm4, %%xmm1\n\t" \ "pslldq $4, %%xmm4\n\t" \ "pxor %%xmm4, %%xmm1\n\t" \ "pxor %%xmm2, %%xmm1\n\t" \ "pshufd $0xff, %%xmm1, %%xmm2\n\t" \ "movdqu %%xmm3, %%xmm4\n\t" \ "pslldq $4, %%xmm4\n\t" \ "pxor %%xmm4, %%xmm3\n\t" \ "pxor %%xmm2, %%xmm3\n\t" asm volatile ("movdqu (%[key]), %%xmm1\n\t" /* xmm1 := key[0..15] */ "movq 16(%[key]), %%xmm3\n\t" /* xmm3 := key[16..23] */ "movdqa %%xmm1, (%[ksch])\n\t" /* ksch[0] := xmm1 */ "movdqa %%xmm3, %%xmm5\n\t" AESKEYGENASSIST_xmm3_xmm2(0x01) AESKEY_EXPAND192 "shufpd $0, %%xmm1, %%xmm5\n\t" "movdqa %%xmm5, 0x10(%[ksch])\n\t" /* ksch[1] := xmm5 */ "movdqa %%xmm1, %%xmm6\n\t" "shufpd $1, %%xmm3, %%xmm6\n\t" "movdqa %%xmm6, 0x20(%[ksch])\n\t" /* ksch[2] := xmm6 */ AESKEYGENASSIST_xmm3_xmm2(0x02) AESKEY_EXPAND192 "movdqa %%xmm1, 0x30(%[ksch])\n\t" /* ksch[3] := xmm1 */ "movdqa %%xmm3, %%xmm5\n\t" AESKEYGENASSIST_xmm3_xmm2(0x04) AESKEY_EXPAND192 "shufpd $0, %%xmm1, %%xmm5\n\t" "movdqa %%xmm5, 0x40(%[ksch])\n\t" /* ksch[4] := xmm5 */ "movdqa %%xmm1, %%xmm6\n\t" "shufpd $1, %%xmm3, %%xmm6\n\t" "movdqa %%xmm6, 0x50(%[ksch])\n\t" /* ksch[5] := xmm6 */ AESKEYGENASSIST_xmm3_xmm2(0x08) AESKEY_EXPAND192 "movdqa %%xmm1, 0x60(%[ksch])\n\t" /* ksch[6] := xmm1 */ "movdqa %%xmm3, %%xmm5\n\t" AESKEYGENASSIST_xmm3_xmm2(0x10) AESKEY_EXPAND192 "shufpd $0, %%xmm1, %%xmm5\n\t" "movdqa %%xmm5, 0x70(%[ksch])\n\t" /* ksch[7] := xmm5 */ "movdqa %%xmm1, %%xmm6\n\t" "shufpd $1, %%xmm3, %%xmm6\n\t" "movdqa %%xmm6, 0x80(%[ksch])\n\t" /* ksch[8] := xmm6 */ AESKEYGENASSIST_xmm3_xmm2(0x20) AESKEY_EXPAND192 "movdqa %%xmm1, 0x90(%[ksch])\n\t" /* ksch[9] := xmm1 */ "movdqa %%xmm3, %%xmm5\n\t" AESKEYGENASSIST_xmm3_xmm2(0x40) AESKEY_EXPAND192 "shufpd $0, %%xmm1, %%xmm5\n\t" "movdqa %%xmm5, 0xa0(%[ksch])\n\t" /* ksch[10] := xmm5 */ "movdqa %%xmm1, %%xmm6\n\t" "shufpd $1, %%xmm3, %%xmm6\n\t" "movdqa %%xmm6, 0xb0(%[ksch])\n\t" /* ksch[11] := xmm6 */ AESKEYGENASSIST_xmm3_xmm2(0x80) AESKEY_EXPAND192 "movdqa %%xmm1, 0xc0(%[ksch])\n\t" /* ksch[12] := xmm1 */ : : [key] "r" (key), [ksch] "r" (ctx->keyschenc) : "cc", "memory" ); #undef AESKEYGENASSIST_xmm3_xmm2 #undef AESKEY_EXPAND192 } else if (ctx->rounds > 12) { /* 256-bit key */ #define AESKEYGENASSIST_xmm1_xmm2(imm8) \ ".byte 0x66, 0x0f, 0x3a, 0xdf, 0xd1, " #imm8 " \n\t" #define AESKEYGENASSIST_xmm3_xmm2(imm8) \ ".byte 0x66, 0x0f, 0x3a, 0xdf, 0xd3, " #imm8 " \n\t" #define AESKEY_EXPAND256_A \ "pshufd $0xff, %%xmm2, %%xmm2\n\t" \ "movdqa %%xmm1, %%xmm4\n\t" \ "pslldq $4, %%xmm4\n\t" \ "pxor %%xmm4, %%xmm1\n\t" \ "pslldq $4, %%xmm4\n\t" \ "pxor %%xmm4, %%xmm1\n\t" \ "pslldq $4, %%xmm4\n\t" \ "pxor %%xmm4, %%xmm1\n\t" \ "pxor %%xmm2, %%xmm1\n\t" #define AESKEY_EXPAND256_B \ "pshufd $0xaa, %%xmm2, %%xmm2\n\t" \ "movdqa %%xmm3, %%xmm4\n\t" \ "pslldq $4, %%xmm4\n\t" \ "pxor %%xmm4, %%xmm3\n\t" \ "pslldq $4, %%xmm4\n\t" \ "pxor %%xmm4, %%xmm3\n\t" \ "pslldq $4, %%xmm4\n\t" \ "pxor %%xmm4, %%xmm3\n\t" \ "pxor %%xmm2, %%xmm3\n\t" asm volatile ("movdqu (%[key]), %%xmm1\n\t" /* xmm1 := key[0..15] */ "movdqu 16(%[key]), %%xmm3\n\t" /* xmm3 := key[16..31] */ "movdqa %%xmm1, (%[ksch])\n\t" /* ksch[0] := xmm1 */ "movdqa %%xmm3, 0x10(%[ksch])\n\t" /* ksch[1] := xmm3 */ AESKEYGENASSIST_xmm3_xmm2(0x01) AESKEY_EXPAND256_A "movdqa %%xmm1, 0x20(%[ksch])\n\t" /* ksch[2] := xmm1 */ AESKEYGENASSIST_xmm1_xmm2(0x00) AESKEY_EXPAND256_B "movdqa %%xmm3, 0x30(%[ksch])\n\t" /* ksch[3] := xmm3 */ AESKEYGENASSIST_xmm3_xmm2(0x02) AESKEY_EXPAND256_A "movdqa %%xmm1, 0x40(%[ksch])\n\t" /* ksch[4] := xmm1 */ AESKEYGENASSIST_xmm1_xmm2(0x00) AESKEY_EXPAND256_B "movdqa %%xmm3, 0x50(%[ksch])\n\t" /* ksch[5] := xmm3 */ AESKEYGENASSIST_xmm3_xmm2(0x04) AESKEY_EXPAND256_A "movdqa %%xmm1, 0x60(%[ksch])\n\t" /* ksch[6] := xmm1 */ AESKEYGENASSIST_xmm1_xmm2(0x00) AESKEY_EXPAND256_B "movdqa %%xmm3, 0x70(%[ksch])\n\t" /* ksch[7] := xmm3 */ AESKEYGENASSIST_xmm3_xmm2(0x08) AESKEY_EXPAND256_A "movdqa %%xmm1, 0x80(%[ksch])\n\t" /* ksch[8] := xmm1 */ AESKEYGENASSIST_xmm1_xmm2(0x00) AESKEY_EXPAND256_B "movdqa %%xmm3, 0x90(%[ksch])\n\t" /* ksch[9] := xmm3 */ AESKEYGENASSIST_xmm3_xmm2(0x10) AESKEY_EXPAND256_A "movdqa %%xmm1, 0xa0(%[ksch])\n\t" /* ksch[10] := xmm1 */ AESKEYGENASSIST_xmm1_xmm2(0x00) AESKEY_EXPAND256_B "movdqa %%xmm3, 0xb0(%[ksch])\n\t" /* ksch[11] := xmm3 */ AESKEYGENASSIST_xmm3_xmm2(0x20) AESKEY_EXPAND256_A "movdqa %%xmm1, 0xc0(%[ksch])\n\t" /* ksch[12] := xmm1 */ AESKEYGENASSIST_xmm1_xmm2(0x00) AESKEY_EXPAND256_B "movdqa %%xmm3, 0xd0(%[ksch])\n\t" /* ksch[13] := xmm3 */ AESKEYGENASSIST_xmm3_xmm2(0x40) AESKEY_EXPAND256_A "movdqa %%xmm1, 0xe0(%[ksch])\n\t" /* ksch[14] := xmm1 */ : : [key] "r" (key), [ksch] "r" (ctx->keyschenc) : "cc", "memory" ); #undef AESKEYGENASSIST_xmm1_xmm2 #undef AESKEYGENASSIST_xmm3_xmm2 #undef AESKEY_EXPAND256_A #undef AESKEY_EXPAND256_B } aesni_cleanup(); aesni_cleanup_2_7(); } /* Make a decryption key from an encryption key. */ static ASM_FUNC_ATTR_INLINE void do_aesni_prepare_decryption (RIJNDAEL_context *ctx) { /* The AES-NI decrypt instructions use the Equivalent Inverse Cipher, thus we can't use the the standard decrypt key preparation. */ u128_t *ekey = (u128_t *)ctx->keyschenc; u128_t *dkey = (u128_t *)ctx->keyschdec; int rr; int r; #define DO_AESNI_AESIMC() \ asm volatile ("movdqa %[ekey], %%xmm1\n\t" \ /*"aesimc %%xmm1, %%xmm1\n\t"*/ \ ".byte 0x66, 0x0f, 0x38, 0xdb, 0xc9\n\t" \ "movdqa %%xmm1, %[dkey]" \ : [dkey] "=m" (dkey[r]) \ : [ekey] "m" (ekey[rr]) \ : "memory") dkey[0] = ekey[ctx->rounds]; r=1; rr=ctx->rounds-1; DO_AESNI_AESIMC(); r++; rr--; /* round 1 */ DO_AESNI_AESIMC(); r++; rr--; /* round 2 */ DO_AESNI_AESIMC(); r++; rr--; /* round 3 */ DO_AESNI_AESIMC(); r++; rr--; /* round 4 */ DO_AESNI_AESIMC(); r++; rr--; /* round 5 */ DO_AESNI_AESIMC(); r++; rr--; /* round 6 */ DO_AESNI_AESIMC(); r++; rr--; /* round 7 */ DO_AESNI_AESIMC(); r++; rr--; /* round 8 */ DO_AESNI_AESIMC(); r++; rr--; /* round 9 */ if (ctx->rounds > 10) { DO_AESNI_AESIMC(); r++; rr--; /* round 10 */ DO_AESNI_AESIMC(); r++; rr--; /* round 11 */ if (ctx->rounds > 12) { DO_AESNI_AESIMC(); r++; rr--; /* round 12 */ DO_AESNI_AESIMC(); r++; rr--; /* round 13 */ } } dkey[r] = ekey[0]; #undef DO_AESNI_AESIMC } void ASM_FUNC_ATTR _gcry_aes_aesni_prepare_decryption (RIJNDAEL_context *ctx) { aesni_prepare(); do_aesni_prepare_decryption (ctx); aesni_cleanup(); } /* Encrypt one block using the Intel AES-NI instructions. Block is input * and output through SSE register xmm0. */ static ASM_FUNC_ATTR_INLINE void do_aesni_enc (const RIJNDAEL_context *ctx) { #define aesenc_xmm1_xmm0 ".byte 0x66, 0x0f, 0x38, 0xdc, 0xc1\n\t" #define aesenclast_xmm1_xmm0 ".byte 0x66, 0x0f, 0x38, 0xdd, 0xc1\n\t" asm volatile ("movdqa (%[key]), %%xmm1\n\t" /* xmm1 := key[0] */ "pxor %%xmm1, %%xmm0\n\t" /* xmm0 ^= key[0] */ "movdqa 0x10(%[key]), %%xmm1\n\t" aesenc_xmm1_xmm0 "movdqa 0x20(%[key]), %%xmm1\n\t" aesenc_xmm1_xmm0 "movdqa 0x30(%[key]), %%xmm1\n\t" aesenc_xmm1_xmm0 "movdqa 0x40(%[key]), %%xmm1\n\t" aesenc_xmm1_xmm0 "movdqa 0x50(%[key]), %%xmm1\n\t" aesenc_xmm1_xmm0 "movdqa 0x60(%[key]), %%xmm1\n\t" aesenc_xmm1_xmm0 "movdqa 0x70(%[key]), %%xmm1\n\t" aesenc_xmm1_xmm0 "movdqa 0x80(%[key]), %%xmm1\n\t" aesenc_xmm1_xmm0 "movdqa 0x90(%[key]), %%xmm1\n\t" aesenc_xmm1_xmm0 "movdqa 0xa0(%[key]), %%xmm1\n\t" "cmpl $10, %[rounds]\n\t" "jz .Lenclast%=\n\t" aesenc_xmm1_xmm0 "movdqa 0xb0(%[key]), %%xmm1\n\t" aesenc_xmm1_xmm0 "movdqa 0xc0(%[key]), %%xmm1\n\t" "cmpl $12, %[rounds]\n\t" "jz .Lenclast%=\n\t" aesenc_xmm1_xmm0 "movdqa 0xd0(%[key]), %%xmm1\n\t" aesenc_xmm1_xmm0 "movdqa 0xe0(%[key]), %%xmm1\n" ".Lenclast%=:\n\t" aesenclast_xmm1_xmm0 "\n" : : [key] "r" (ctx->keyschenc), [rounds] "r" (ctx->rounds) : "cc", "memory"); #undef aesenc_xmm1_xmm0 #undef aesenclast_xmm1_xmm0 } /* Decrypt one block using the Intel AES-NI instructions. Block is input * and output through SSE register xmm0. */ static ASM_FUNC_ATTR_INLINE void do_aesni_dec (const RIJNDAEL_context *ctx) { #define aesdec_xmm1_xmm0 ".byte 0x66, 0x0f, 0x38, 0xde, 0xc1\n\t" #define aesdeclast_xmm1_xmm0 ".byte 0x66, 0x0f, 0x38, 0xdf, 0xc1\n\t" asm volatile ("movdqa (%[key]), %%xmm1\n\t" "pxor %%xmm1, %%xmm0\n\t" /* xmm0 ^= key[0] */ "movdqa 0x10(%[key]), %%xmm1\n\t" aesdec_xmm1_xmm0 "movdqa 0x20(%[key]), %%xmm1\n\t" aesdec_xmm1_xmm0 "movdqa 0x30(%[key]), %%xmm1\n\t" aesdec_xmm1_xmm0 "movdqa 0x40(%[key]), %%xmm1\n\t" aesdec_xmm1_xmm0 "movdqa 0x50(%[key]), %%xmm1\n\t" aesdec_xmm1_xmm0 "movdqa 0x60(%[key]), %%xmm1\n\t" aesdec_xmm1_xmm0 "movdqa 0x70(%[key]), %%xmm1\n\t" aesdec_xmm1_xmm0 "movdqa 0x80(%[key]), %%xmm1\n\t" aesdec_xmm1_xmm0 "movdqa 0x90(%[key]), %%xmm1\n\t" aesdec_xmm1_xmm0 "movdqa 0xa0(%[key]), %%xmm1\n\t" "cmpl $10, %[rounds]\n\t" "jz .Ldeclast%=\n\t" aesdec_xmm1_xmm0 "movdqa 0xb0(%[key]), %%xmm1\n\t" aesdec_xmm1_xmm0 "movdqa 0xc0(%[key]), %%xmm1\n\t" "cmpl $12, %[rounds]\n\t" "jz .Ldeclast%=\n\t" aesdec_xmm1_xmm0 "movdqa 0xd0(%[key]), %%xmm1\n\t" aesdec_xmm1_xmm0 "movdqa 0xe0(%[key]), %%xmm1\n" ".Ldeclast%=:\n\t" aesdeclast_xmm1_xmm0 "\n" : : [key] "r" (ctx->keyschdec), [rounds] "r" (ctx->rounds) : "cc", "memory"); #undef aesdec_xmm1_xmm0 #undef aesdeclast_xmm1_xmm0 } /* Encrypt four blocks using the Intel AES-NI instructions. Blocks are input * and output through SSE registers xmm1 to xmm4. */ static ASM_FUNC_ATTR_INLINE void do_aesni_enc_vec4 (const RIJNDAEL_context *ctx) { #define aesenc_xmm0_xmm1 ".byte 0x66, 0x0f, 0x38, 0xdc, 0xc8\n\t" #define aesenc_xmm0_xmm2 ".byte 0x66, 0x0f, 0x38, 0xdc, 0xd0\n\t" #define aesenc_xmm0_xmm3 ".byte 0x66, 0x0f, 0x38, 0xdc, 0xd8\n\t" #define aesenc_xmm0_xmm4 ".byte 0x66, 0x0f, 0x38, 0xdc, 0xe0\n\t" #define aesenclast_xmm0_xmm1 ".byte 0x66, 0x0f, 0x38, 0xdd, 0xc8\n\t" #define aesenclast_xmm0_xmm2 ".byte 0x66, 0x0f, 0x38, 0xdd, 0xd0\n\t" #define aesenclast_xmm0_xmm3 ".byte 0x66, 0x0f, 0x38, 0xdd, 0xd8\n\t" #define aesenclast_xmm0_xmm4 ".byte 0x66, 0x0f, 0x38, 0xdd, 0xe0\n\t" asm volatile ("movdqa (%[key]), %%xmm0\n\t" "pxor %%xmm0, %%xmm1\n\t" /* xmm1 ^= key[0] */ "pxor %%xmm0, %%xmm2\n\t" /* xmm2 ^= key[0] */ "pxor %%xmm0, %%xmm3\n\t" /* xmm3 ^= key[0] */ "pxor %%xmm0, %%xmm4\n\t" /* xmm4 ^= key[0] */ "movdqa 0x10(%[key]), %%xmm0\n\t" aesenc_xmm0_xmm1 aesenc_xmm0_xmm2 aesenc_xmm0_xmm3 aesenc_xmm0_xmm4 "movdqa 0x20(%[key]), %%xmm0\n\t" aesenc_xmm0_xmm1 aesenc_xmm0_xmm2 aesenc_xmm0_xmm3 aesenc_xmm0_xmm4 "movdqa 0x30(%[key]), %%xmm0\n\t" aesenc_xmm0_xmm1 aesenc_xmm0_xmm2 aesenc_xmm0_xmm3 aesenc_xmm0_xmm4 "movdqa 0x40(%[key]), %%xmm0\n\t" aesenc_xmm0_xmm1 aesenc_xmm0_xmm2 aesenc_xmm0_xmm3 aesenc_xmm0_xmm4 "movdqa 0x50(%[key]), %%xmm0\n\t" aesenc_xmm0_xmm1 aesenc_xmm0_xmm2 aesenc_xmm0_xmm3 aesenc_xmm0_xmm4 "movdqa 0x60(%[key]), %%xmm0\n\t" aesenc_xmm0_xmm1 aesenc_xmm0_xmm2 aesenc_xmm0_xmm3 aesenc_xmm0_xmm4 "movdqa 0x70(%[key]), %%xmm0\n\t" aesenc_xmm0_xmm1 aesenc_xmm0_xmm2 aesenc_xmm0_xmm3 aesenc_xmm0_xmm4 "movdqa 0x80(%[key]), %%xmm0\n\t" aesenc_xmm0_xmm1 aesenc_xmm0_xmm2 aesenc_xmm0_xmm3 aesenc_xmm0_xmm4 "movdqa 0x90(%[key]), %%xmm0\n\t" aesenc_xmm0_xmm1 aesenc_xmm0_xmm2 aesenc_xmm0_xmm3 aesenc_xmm0_xmm4 "movdqa 0xa0(%[key]), %%xmm0\n\t" "cmpl $10, %[rounds]\n\t" "jz .Ldeclast%=\n\t" aesenc_xmm0_xmm1 aesenc_xmm0_xmm2 aesenc_xmm0_xmm3 aesenc_xmm0_xmm4 "movdqa 0xb0(%[key]), %%xmm0\n\t" aesenc_xmm0_xmm1 aesenc_xmm0_xmm2 aesenc_xmm0_xmm3 aesenc_xmm0_xmm4 "movdqa 0xc0(%[key]), %%xmm0\n\t" "cmpl $12, %[rounds]\n\t" "jz .Ldeclast%=\n\t" aesenc_xmm0_xmm1 aesenc_xmm0_xmm2 aesenc_xmm0_xmm3 aesenc_xmm0_xmm4 "movdqa 0xd0(%[key]), %%xmm0\n\t" aesenc_xmm0_xmm1 aesenc_xmm0_xmm2 aesenc_xmm0_xmm3 aesenc_xmm0_xmm4 "movdqa 0xe0(%[key]), %%xmm0\n" ".Ldeclast%=:\n\t" aesenclast_xmm0_xmm1 aesenclast_xmm0_xmm2 aesenclast_xmm0_xmm3 aesenclast_xmm0_xmm4 : /* no output */ : [key] "r" (ctx->keyschenc), [rounds] "r" (ctx->rounds) : "cc", "memory"); #undef aesenc_xmm0_xmm1 #undef aesenc_xmm0_xmm2 #undef aesenc_xmm0_xmm3 #undef aesenc_xmm0_xmm4 #undef aesenclast_xmm0_xmm1 #undef aesenclast_xmm0_xmm2 #undef aesenclast_xmm0_xmm3 #undef aesenclast_xmm0_xmm4 } /* Decrypt four blocks using the Intel AES-NI instructions. Blocks are input * and output through SSE registers xmm1 to xmm4. */ static ASM_FUNC_ATTR_INLINE void do_aesni_dec_vec4 (const RIJNDAEL_context *ctx) { #define aesdec_xmm0_xmm1 ".byte 0x66, 0x0f, 0x38, 0xde, 0xc8\n\t" #define aesdec_xmm0_xmm2 ".byte 0x66, 0x0f, 0x38, 0xde, 0xd0\n\t" #define aesdec_xmm0_xmm3 ".byte 0x66, 0x0f, 0x38, 0xde, 0xd8\n\t" #define aesdec_xmm0_xmm4 ".byte 0x66, 0x0f, 0x38, 0xde, 0xe0\n\t" #define aesdeclast_xmm0_xmm1 ".byte 0x66, 0x0f, 0x38, 0xdf, 0xc8\n\t" #define aesdeclast_xmm0_xmm2 ".byte 0x66, 0x0f, 0x38, 0xdf, 0xd0\n\t" #define aesdeclast_xmm0_xmm3 ".byte 0x66, 0x0f, 0x38, 0xdf, 0xd8\n\t" #define aesdeclast_xmm0_xmm4 ".byte 0x66, 0x0f, 0x38, 0xdf, 0xe0\n\t" asm volatile ("movdqa (%[key]), %%xmm0\n\t" "pxor %%xmm0, %%xmm1\n\t" /* xmm1 ^= key[0] */ "pxor %%xmm0, %%xmm2\n\t" /* xmm2 ^= key[0] */ "pxor %%xmm0, %%xmm3\n\t" /* xmm3 ^= key[0] */ "pxor %%xmm0, %%xmm4\n\t" /* xmm4 ^= key[0] */ "movdqa 0x10(%[key]), %%xmm0\n\t" aesdec_xmm0_xmm1 aesdec_xmm0_xmm2 aesdec_xmm0_xmm3 aesdec_xmm0_xmm4 "movdqa 0x20(%[key]), %%xmm0\n\t" aesdec_xmm0_xmm1 aesdec_xmm0_xmm2 aesdec_xmm0_xmm3 aesdec_xmm0_xmm4 "movdqa 0x30(%[key]), %%xmm0\n\t" aesdec_xmm0_xmm1 aesdec_xmm0_xmm2 aesdec_xmm0_xmm3 aesdec_xmm0_xmm4 "movdqa 0x40(%[key]), %%xmm0\n\t" aesdec_xmm0_xmm1 aesdec_xmm0_xmm2 aesdec_xmm0_xmm3 aesdec_xmm0_xmm4 "movdqa 0x50(%[key]), %%xmm0\n\t" aesdec_xmm0_xmm1 aesdec_xmm0_xmm2 aesdec_xmm0_xmm3 aesdec_xmm0_xmm4 "movdqa 0x60(%[key]), %%xmm0\n\t" aesdec_xmm0_xmm1 aesdec_xmm0_xmm2 aesdec_xmm0_xmm3 aesdec_xmm0_xmm4 "movdqa 0x70(%[key]), %%xmm0\n\t" aesdec_xmm0_xmm1 aesdec_xmm0_xmm2 aesdec_xmm0_xmm3 aesdec_xmm0_xmm4 "movdqa 0x80(%[key]), %%xmm0\n\t" aesdec_xmm0_xmm1 aesdec_xmm0_xmm2 aesdec_xmm0_xmm3 aesdec_xmm0_xmm4 "movdqa 0x90(%[key]), %%xmm0\n\t" aesdec_xmm0_xmm1 aesdec_xmm0_xmm2 aesdec_xmm0_xmm3 aesdec_xmm0_xmm4 "movdqa 0xa0(%[key]), %%xmm0\n\t" "cmpl $10, %[rounds]\n\t" "jz .Ldeclast%=\n\t" aesdec_xmm0_xmm1 aesdec_xmm0_xmm2 aesdec_xmm0_xmm3 aesdec_xmm0_xmm4 "movdqa 0xb0(%[key]), %%xmm0\n\t" aesdec_xmm0_xmm1 aesdec_xmm0_xmm2 aesdec_xmm0_xmm3 aesdec_xmm0_xmm4 "movdqa 0xc0(%[key]), %%xmm0\n\t" "cmpl $12, %[rounds]\n\t" "jz .Ldeclast%=\n\t" aesdec_xmm0_xmm1 aesdec_xmm0_xmm2 aesdec_xmm0_xmm3 aesdec_xmm0_xmm4 "movdqa 0xd0(%[key]), %%xmm0\n\t" aesdec_xmm0_xmm1 aesdec_xmm0_xmm2 aesdec_xmm0_xmm3 aesdec_xmm0_xmm4 "movdqa 0xe0(%[key]), %%xmm0\n" ".Ldeclast%=:\n\t" aesdeclast_xmm0_xmm1 aesdeclast_xmm0_xmm2 aesdeclast_xmm0_xmm3 aesdeclast_xmm0_xmm4 : /* no output */ : [key] "r" (ctx->keyschdec), [rounds] "r" (ctx->rounds) : "cc", "memory"); #undef aesdec_xmm0_xmm1 #undef aesdec_xmm0_xmm2 #undef aesdec_xmm0_xmm3 #undef aesdec_xmm0_xmm4 #undef aesdeclast_xmm0_xmm1 #undef aesdeclast_xmm0_xmm2 #undef aesdeclast_xmm0_xmm3 #undef aesdeclast_xmm0_xmm4 } #ifdef __x86_64__ /* Encrypt eight blocks using the Intel AES-NI instructions. Blocks are input * and output through SSE registers xmm1 to xmm4 and xmm8 to xmm11. */ static ASM_FUNC_ATTR_INLINE void do_aesni_enc_vec8 (const RIJNDAEL_context *ctx) { asm volatile ("movdqa 0x10(%[key]), %%xmm0\n\t" "aesenc %%xmm0, %%xmm1\n\t" "aesenc %%xmm0, %%xmm2\n\t" "aesenc %%xmm0, %%xmm3\n\t" "aesenc %%xmm0, %%xmm4\n\t" "aesenc %%xmm0, %%xmm8\n\t" "aesenc %%xmm0, %%xmm9\n\t" "aesenc %%xmm0, %%xmm10\n\t" "aesenc %%xmm0, %%xmm11\n\t" "movdqa 0x20(%[key]), %%xmm0\n\t" "cmpl $12, %[rounds]\n\t" "aesenc %%xmm0, %%xmm1\n\t" "aesenc %%xmm0, %%xmm2\n\t" "aesenc %%xmm0, %%xmm3\n\t" "aesenc %%xmm0, %%xmm4\n\t" "aesenc %%xmm0, %%xmm8\n\t" "aesenc %%xmm0, %%xmm9\n\t" "aesenc %%xmm0, %%xmm10\n\t" "aesenc %%xmm0, %%xmm11\n\t" "movdqa 0x30(%[key]), %%xmm0\n\t" "aesenc %%xmm0, %%xmm1\n\t" "aesenc %%xmm0, %%xmm2\n\t" "aesenc %%xmm0, %%xmm3\n\t" "aesenc %%xmm0, %%xmm4\n\t" "aesenc %%xmm0, %%xmm8\n\t" "aesenc %%xmm0, %%xmm9\n\t" "aesenc %%xmm0, %%xmm10\n\t" "aesenc %%xmm0, %%xmm11\n\t" "movdqa 0x40(%[key]), %%xmm0\n\t" "aesenc %%xmm0, %%xmm1\n\t" "aesenc %%xmm0, %%xmm2\n\t" "aesenc %%xmm0, %%xmm3\n\t" "aesenc %%xmm0, %%xmm4\n\t" "aesenc %%xmm0, %%xmm8\n\t" "aesenc %%xmm0, %%xmm9\n\t" "aesenc %%xmm0, %%xmm10\n\t" "aesenc %%xmm0, %%xmm11\n\t" "movdqa 0x50(%[key]), %%xmm0\n\t" "aesenc %%xmm0, %%xmm1\n\t" "aesenc %%xmm0, %%xmm2\n\t" "aesenc %%xmm0, %%xmm3\n\t" "aesenc %%xmm0, %%xmm4\n\t" "aesenc %%xmm0, %%xmm8\n\t" "aesenc %%xmm0, %%xmm9\n\t" "aesenc %%xmm0, %%xmm10\n\t" "aesenc %%xmm0, %%xmm11\n\t" "movdqa 0x60(%[key]), %%xmm0\n\t" "aesenc %%xmm0, %%xmm1\n\t" "aesenc %%xmm0, %%xmm2\n\t" "aesenc %%xmm0, %%xmm3\n\t" "aesenc %%xmm0, %%xmm4\n\t" "aesenc %%xmm0, %%xmm8\n\t" "aesenc %%xmm0, %%xmm9\n\t" "aesenc %%xmm0, %%xmm10\n\t" "aesenc %%xmm0, %%xmm11\n\t" "movdqa 0x70(%[key]), %%xmm0\n\t" "aesenc %%xmm0, %%xmm1\n\t" "aesenc %%xmm0, %%xmm2\n\t" "aesenc %%xmm0, %%xmm3\n\t" "aesenc %%xmm0, %%xmm4\n\t" "aesenc %%xmm0, %%xmm8\n\t" "aesenc %%xmm0, %%xmm9\n\t" "aesenc %%xmm0, %%xmm10\n\t" "aesenc %%xmm0, %%xmm11\n\t" "movdqa 0x80(%[key]), %%xmm0\n\t" "aesenc %%xmm0, %%xmm1\n\t" "aesenc %%xmm0, %%xmm2\n\t" "aesenc %%xmm0, %%xmm3\n\t" "aesenc %%xmm0, %%xmm4\n\t" "aesenc %%xmm0, %%xmm8\n\t" "aesenc %%xmm0, %%xmm9\n\t" "aesenc %%xmm0, %%xmm10\n\t" "aesenc %%xmm0, %%xmm11\n\t" "movdqa 0x90(%[key]), %%xmm0\n\t" "aesenc %%xmm0, %%xmm1\n\t" "aesenc %%xmm0, %%xmm2\n\t" "aesenc %%xmm0, %%xmm3\n\t" "aesenc %%xmm0, %%xmm4\n\t" "aesenc %%xmm0, %%xmm8\n\t" "aesenc %%xmm0, %%xmm9\n\t" "aesenc %%xmm0, %%xmm10\n\t" "aesenc %%xmm0, %%xmm11\n\t" "movdqa 0xa0(%[key]), %%xmm0\n\t" "jb .Ldeclast%=\n\t" "aesenc %%xmm0, %%xmm1\n\t" "aesenc %%xmm0, %%xmm2\n\t" "aesenc %%xmm0, %%xmm3\n\t" "aesenc %%xmm0, %%xmm4\n\t" "aesenc %%xmm0, %%xmm8\n\t" "aesenc %%xmm0, %%xmm9\n\t" "aesenc %%xmm0, %%xmm10\n\t" "aesenc %%xmm0, %%xmm11\n\t" "movdqa 0xb0(%[key]), %%xmm0\n\t" "aesenc %%xmm0, %%xmm1\n\t" "aesenc %%xmm0, %%xmm2\n\t" "aesenc %%xmm0, %%xmm3\n\t" "aesenc %%xmm0, %%xmm4\n\t" "aesenc %%xmm0, %%xmm8\n\t" "aesenc %%xmm0, %%xmm9\n\t" "aesenc %%xmm0, %%xmm10\n\t" "aesenc %%xmm0, %%xmm11\n\t" "movdqa 0xc0(%[key]), %%xmm0\n\t" "je .Ldeclast%=\n\t" "aesenc %%xmm0, %%xmm1\n\t" "aesenc %%xmm0, %%xmm2\n\t" "aesenc %%xmm0, %%xmm3\n\t" "aesenc %%xmm0, %%xmm4\n\t" "aesenc %%xmm0, %%xmm8\n\t" "aesenc %%xmm0, %%xmm9\n\t" "aesenc %%xmm0, %%xmm10\n\t" "aesenc %%xmm0, %%xmm11\n\t" "movdqa 0xd0(%[key]), %%xmm0\n\t" "aesenc %%xmm0, %%xmm1\n\t" "aesenc %%xmm0, %%xmm2\n\t" "aesenc %%xmm0, %%xmm3\n\t" "aesenc %%xmm0, %%xmm4\n\t" "aesenc %%xmm0, %%xmm8\n\t" "aesenc %%xmm0, %%xmm9\n\t" "aesenc %%xmm0, %%xmm10\n\t" "aesenc %%xmm0, %%xmm11\n\t" "movdqa 0xe0(%[key]), %%xmm0\n" ".Ldeclast%=:\n\t" : /* no output */ : [key] "r" (ctx->keyschenc), [rounds] "r" (ctx->rounds) : "cc", "memory"); } /* Decrypt eight blocks using the Intel AES-NI instructions. Blocks are input * and output through SSE registers xmm1 to xmm4 and xmm8 to xmm11. */ static ASM_FUNC_ATTR_INLINE void do_aesni_dec_vec8 (const RIJNDAEL_context *ctx) { asm volatile ("movdqa 0x10(%[key]), %%xmm0\n\t" "cmpl $12, %[rounds]\n\t" "aesdec %%xmm0, %%xmm1\n\t" "aesdec %%xmm0, %%xmm2\n\t" "aesdec %%xmm0, %%xmm3\n\t" "aesdec %%xmm0, %%xmm4\n\t" "aesdec %%xmm0, %%xmm8\n\t" "aesdec %%xmm0, %%xmm9\n\t" "aesdec %%xmm0, %%xmm10\n\t" "aesdec %%xmm0, %%xmm11\n\t" "movdqa 0x20(%[key]), %%xmm0\n\t" "aesdec %%xmm0, %%xmm1\n\t" "aesdec %%xmm0, %%xmm2\n\t" "aesdec %%xmm0, %%xmm3\n\t" "aesdec %%xmm0, %%xmm4\n\t" "aesdec %%xmm0, %%xmm8\n\t" "aesdec %%xmm0, %%xmm9\n\t" "aesdec %%xmm0, %%xmm10\n\t" "aesdec %%xmm0, %%xmm11\n\t" "movdqa 0x30(%[key]), %%xmm0\n\t" "aesdec %%xmm0, %%xmm1\n\t" "aesdec %%xmm0, %%xmm2\n\t" "aesdec %%xmm0, %%xmm3\n\t" "aesdec %%xmm0, %%xmm4\n\t" "aesdec %%xmm0, %%xmm8\n\t" "aesdec %%xmm0, %%xmm9\n\t" "aesdec %%xmm0, %%xmm10\n\t" "aesdec %%xmm0, %%xmm11\n\t" "movdqa 0x40(%[key]), %%xmm0\n\t" "aesdec %%xmm0, %%xmm1\n\t" "aesdec %%xmm0, %%xmm2\n\t" "aesdec %%xmm0, %%xmm3\n\t" "aesdec %%xmm0, %%xmm4\n\t" "aesdec %%xmm0, %%xmm8\n\t" "aesdec %%xmm0, %%xmm9\n\t" "aesdec %%xmm0, %%xmm10\n\t" "aesdec %%xmm0, %%xmm11\n\t" "movdqa 0x50(%[key]), %%xmm0\n\t" "aesdec %%xmm0, %%xmm1\n\t" "aesdec %%xmm0, %%xmm2\n\t" "aesdec %%xmm0, %%xmm3\n\t" "aesdec %%xmm0, %%xmm4\n\t" "aesdec %%xmm0, %%xmm8\n\t" "aesdec %%xmm0, %%xmm9\n\t" "aesdec %%xmm0, %%xmm10\n\t" "aesdec %%xmm0, %%xmm11\n\t" "movdqa 0x60(%[key]), %%xmm0\n\t" "aesdec %%xmm0, %%xmm1\n\t" "aesdec %%xmm0, %%xmm2\n\t" "aesdec %%xmm0, %%xmm3\n\t" "aesdec %%xmm0, %%xmm4\n\t" "aesdec %%xmm0, %%xmm8\n\t" "aesdec %%xmm0, %%xmm9\n\t" "aesdec %%xmm0, %%xmm10\n\t" "aesdec %%xmm0, %%xmm11\n\t" "movdqa 0x70(%[key]), %%xmm0\n\t" "aesdec %%xmm0, %%xmm1\n\t" "aesdec %%xmm0, %%xmm2\n\t" "aesdec %%xmm0, %%xmm3\n\t" "aesdec %%xmm0, %%xmm4\n\t" "aesdec %%xmm0, %%xmm8\n\t" "aesdec %%xmm0, %%xmm9\n\t" "aesdec %%xmm0, %%xmm10\n\t" "aesdec %%xmm0, %%xmm11\n\t" "movdqa 0x80(%[key]), %%xmm0\n\t" "aesdec %%xmm0, %%xmm1\n\t" "aesdec %%xmm0, %%xmm2\n\t" "aesdec %%xmm0, %%xmm3\n\t" "aesdec %%xmm0, %%xmm4\n\t" "aesdec %%xmm0, %%xmm8\n\t" "aesdec %%xmm0, %%xmm9\n\t" "aesdec %%xmm0, %%xmm10\n\t" "aesdec %%xmm0, %%xmm11\n\t" "movdqa 0x90(%[key]), %%xmm0\n\t" "aesdec %%xmm0, %%xmm1\n\t" "aesdec %%xmm0, %%xmm2\n\t" "aesdec %%xmm0, %%xmm3\n\t" "aesdec %%xmm0, %%xmm4\n\t" "aesdec %%xmm0, %%xmm8\n\t" "aesdec %%xmm0, %%xmm9\n\t" "aesdec %%xmm0, %%xmm10\n\t" "aesdec %%xmm0, %%xmm11\n\t" "movdqa 0xa0(%[key]), %%xmm0\n\t" "jb .Ldeclast%=\n\t" "aesdec %%xmm0, %%xmm1\n\t" "aesdec %%xmm0, %%xmm2\n\t" "aesdec %%xmm0, %%xmm3\n\t" "aesdec %%xmm0, %%xmm4\n\t" "aesdec %%xmm0, %%xmm8\n\t" "aesdec %%xmm0, %%xmm9\n\t" "aesdec %%xmm0, %%xmm10\n\t" "aesdec %%xmm0, %%xmm11\n\t" "movdqa 0xb0(%[key]), %%xmm0\n\t" "aesdec %%xmm0, %%xmm1\n\t" "aesdec %%xmm0, %%xmm2\n\t" "aesdec %%xmm0, %%xmm3\n\t" "aesdec %%xmm0, %%xmm4\n\t" "aesdec %%xmm0, %%xmm8\n\t" "aesdec %%xmm0, %%xmm9\n\t" "aesdec %%xmm0, %%xmm10\n\t" "aesdec %%xmm0, %%xmm11\n\t" "movdqa 0xc0(%[key]), %%xmm0\n\t" "je .Ldeclast%=\n\t" "aesdec %%xmm0, %%xmm1\n\t" "aesdec %%xmm0, %%xmm2\n\t" "aesdec %%xmm0, %%xmm3\n\t" "aesdec %%xmm0, %%xmm4\n\t" "aesdec %%xmm0, %%xmm8\n\t" "aesdec %%xmm0, %%xmm9\n\t" "aesdec %%xmm0, %%xmm10\n\t" "aesdec %%xmm0, %%xmm11\n\t" "movdqa 0xd0(%[key]), %%xmm0\n\t" "aesdec %%xmm0, %%xmm1\n\t" "aesdec %%xmm0, %%xmm2\n\t" "aesdec %%xmm0, %%xmm3\n\t" "aesdec %%xmm0, %%xmm4\n\t" "aesdec %%xmm0, %%xmm8\n\t" "aesdec %%xmm0, %%xmm9\n\t" "aesdec %%xmm0, %%xmm10\n\t" "aesdec %%xmm0, %%xmm11\n\t" "movdqa 0xe0(%[key]), %%xmm0\n" ".Ldeclast%=:\n\t" : /* no output */ : [key] "r" (ctx->keyschdec), [rounds] "r" (ctx->rounds) : "cc", "memory"); } #endif /* __x86_64__ */ /* Perform a CTR encryption round using the counter CTR and the input block A. Write the result to the output block B and update CTR. CTR needs to be a 16 byte aligned little-endian value. */ static ASM_FUNC_ATTR_INLINE void do_aesni_ctr (const RIJNDAEL_context *ctx, unsigned char *ctr, unsigned char *b, const unsigned char *a) { #define aesenc_xmm1_xmm0 ".byte 0x66, 0x0f, 0x38, 0xdc, 0xc1\n\t" #define aesenclast_xmm1_xmm0 ".byte 0x66, 0x0f, 0x38, 0xdd, 0xc1\n\t" asm volatile ("movdqa %%xmm5, %%xmm0\n\t" /* xmm0 := CTR (xmm5) */ "pcmpeqd %%xmm1, %%xmm1\n\t" "psrldq $8, %%xmm1\n\t" /* xmm1 = -1 */ "pshufb %%xmm6, %%xmm5\n\t" "psubq %%xmm1, %%xmm5\n\t" /* xmm5++ (big endian) */ /* detect if 64-bit carry handling is needed */ "cmpl $0xffffffff, 8(%[ctr])\n\t" "jne .Lno_carry%=\n\t" "cmpl $0xffffffff, 12(%[ctr])\n\t" "jne .Lno_carry%=\n\t" "pslldq $8, %%xmm1\n\t" /* move lower 64-bit to high */ "psubq %%xmm1, %%xmm5\n\t" /* add carry to upper 64bits */ ".Lno_carry%=:\n\t" "pshufb %%xmm6, %%xmm5\n\t" "movdqa %%xmm5, (%[ctr])\n\t" /* Update CTR (mem). */ "pxor (%[key]), %%xmm0\n\t" /* xmm1 ^= key[0] */ "movdqa 0x10(%[key]), %%xmm1\n\t" aesenc_xmm1_xmm0 "movdqa 0x20(%[key]), %%xmm1\n\t" aesenc_xmm1_xmm0 "movdqa 0x30(%[key]), %%xmm1\n\t" aesenc_xmm1_xmm0 "movdqa 0x40(%[key]), %%xmm1\n\t" aesenc_xmm1_xmm0 "movdqa 0x50(%[key]), %%xmm1\n\t" aesenc_xmm1_xmm0 "movdqa 0x60(%[key]), %%xmm1\n\t" aesenc_xmm1_xmm0 "movdqa 0x70(%[key]), %%xmm1\n\t" aesenc_xmm1_xmm0 "movdqa 0x80(%[key]), %%xmm1\n\t" aesenc_xmm1_xmm0 "movdqa 0x90(%[key]), %%xmm1\n\t" aesenc_xmm1_xmm0 "movdqa 0xa0(%[key]), %%xmm1\n\t" "cmpl $10, %[rounds]\n\t" "jz .Lenclast%=\n\t" aesenc_xmm1_xmm0 "movdqa 0xb0(%[key]), %%xmm1\n\t" aesenc_xmm1_xmm0 "movdqa 0xc0(%[key]), %%xmm1\n\t" "cmpl $12, %[rounds]\n\t" "jz .Lenclast%=\n\t" aesenc_xmm1_xmm0 "movdqa 0xd0(%[key]), %%xmm1\n\t" aesenc_xmm1_xmm0 "movdqa 0xe0(%[key]), %%xmm1\n" ".Lenclast%=:\n\t" aesenclast_xmm1_xmm0 "movdqu %[src], %%xmm1\n\t" /* xmm1 := input */ "pxor %%xmm1, %%xmm0\n\t" /* EncCTR ^= input */ "movdqu %%xmm0, %[dst]" /* Store EncCTR. */ : [dst] "=m" (*b) : [src] "m" (*a), [ctr] "r" (ctr), [key] "r" (ctx->keyschenc), [rounds] "g" (ctx->rounds) : "cc", "memory"); #undef aesenc_xmm1_xmm0 #undef aesenclast_xmm1_xmm0 } /* Four blocks at a time variant of do_aesni_ctr. */ static ASM_FUNC_ATTR_INLINE void do_aesni_ctr_4 (const RIJNDAEL_context *ctx, unsigned char *ctr, unsigned char *b, const unsigned char *a) { static const byte bige_addb_const[4][16] __attribute__ ((aligned (16))) = { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4 } }; const void *bige_addb = bige_addb_const; #define aesenc_xmm1_xmm0 ".byte 0x66, 0x0f, 0x38, 0xdc, 0xc1\n\t" #define aesenc_xmm1_xmm2 ".byte 0x66, 0x0f, 0x38, 0xdc, 0xd1\n\t" #define aesenc_xmm1_xmm3 ".byte 0x66, 0x0f, 0x38, 0xdc, 0xd9\n\t" #define aesenc_xmm1_xmm4 ".byte 0x66, 0x0f, 0x38, 0xdc, 0xe1\n\t" #define aesenclast_xmm1_xmm0 ".byte 0x66, 0x0f, 0x38, 0xdd, 0xc1\n\t" #define aesenclast_xmm1_xmm2 ".byte 0x66, 0x0f, 0x38, 0xdd, 0xd1\n\t" #define aesenclast_xmm1_xmm3 ".byte 0x66, 0x0f, 0x38, 0xdd, 0xd9\n\t" #define aesenclast_xmm1_xmm4 ".byte 0x66, 0x0f, 0x38, 0xdd, 0xe1\n\t" /* Register usage: [key] keyschedule xmm0 CTR-0 xmm1 temp / round key xmm2 CTR-1 xmm3 CTR-2 xmm4 CTR-3 xmm5 copy of *ctr xmm6 endian swapping mask */ asm volatile (/* detect if 8-bit carry handling is needed */ "addb $4, 15(%[ctr])\n\t" "jc .Ladd32bit%=\n\t" "movdqa %%xmm5, %%xmm0\n\t" /* xmm0 := CTR (xmm5) */ "movdqa 0*16(%[addb]), %%xmm2\n\t" /* xmm2 := be(1) */ "movdqa 1*16(%[addb]), %%xmm3\n\t" /* xmm3 := be(2) */ "movdqa 2*16(%[addb]), %%xmm4\n\t" /* xmm4 := be(3) */ "movdqa 3*16(%[addb]), %%xmm5\n\t" /* xmm5 := be(4) */ "paddb %%xmm0, %%xmm2\n\t" /* xmm2 := be(1) + CTR (xmm0) */ "paddb %%xmm0, %%xmm3\n\t" /* xmm3 := be(2) + CTR (xmm0) */ "paddb %%xmm0, %%xmm4\n\t" /* xmm4 := be(3) + CTR (xmm0) */ "paddb %%xmm0, %%xmm5\n\t" /* xmm5 := be(4) + CTR (xmm0) */ "movdqa (%[key]), %%xmm1\n\t" /* xmm1 := key[0] */ "jmp .Ldone_ctr%=\n\t" ".Ladd32bit%=:\n\t" "movdqa %%xmm5, (%[ctr])\n\t" /* Restore CTR. */ "movdqa %%xmm5, %%xmm0\n\t" /* xmm0, xmm2 := CTR (xmm5) */ "movdqa %%xmm0, %%xmm2\n\t" "pcmpeqd %%xmm1, %%xmm1\n\t" "psrldq $8, %%xmm1\n\t" /* xmm1 = -1 */ "pshufb %%xmm6, %%xmm2\n\t" /* xmm2 := le(xmm2) */ "psubq %%xmm1, %%xmm2\n\t" /* xmm2++ */ "movdqa %%xmm2, %%xmm3\n\t" /* xmm3 := xmm2 */ "psubq %%xmm1, %%xmm3\n\t" /* xmm3++ */ "movdqa %%xmm3, %%xmm4\n\t" /* xmm4 := xmm3 */ "psubq %%xmm1, %%xmm4\n\t" /* xmm4++ */ "movdqa %%xmm4, %%xmm5\n\t" /* xmm5 := xmm4 */ "psubq %%xmm1, %%xmm5\n\t" /* xmm5++ */ /* detect if 64-bit carry handling is needed */ "cmpl $0xffffffff, 8(%[ctr])\n\t" "jne .Lno_carry%=\n\t" "movl 12(%[ctr]), %%esi\n\t" "bswapl %%esi\n\t" "cmpl $0xfffffffc, %%esi\n\t" "jb .Lno_carry%=\n\t" /* no carry */ "pslldq $8, %%xmm1\n\t" /* move lower 64-bit to high */ "je .Lcarry_xmm5%=\n\t" /* esi == 0xfffffffc */ "cmpl $0xfffffffe, %%esi\n\t" "jb .Lcarry_xmm4%=\n\t" /* esi == 0xfffffffd */ "je .Lcarry_xmm3%=\n\t" /* esi == 0xfffffffe */ /* esi == 0xffffffff */ "psubq %%xmm1, %%xmm2\n\t" ".Lcarry_xmm3%=:\n\t" "psubq %%xmm1, %%xmm3\n\t" ".Lcarry_xmm4%=:\n\t" "psubq %%xmm1, %%xmm4\n\t" ".Lcarry_xmm5%=:\n\t" "psubq %%xmm1, %%xmm5\n\t" ".Lno_carry%=:\n\t" "movdqa (%[key]), %%xmm1\n\t" /* xmm1 := key[0] */ "pshufb %%xmm6, %%xmm2\n\t" /* xmm2 := be(xmm2) */ "pshufb %%xmm6, %%xmm3\n\t" /* xmm3 := be(xmm3) */ "pshufb %%xmm6, %%xmm4\n\t" /* xmm4 := be(xmm4) */ "pshufb %%xmm6, %%xmm5\n\t" /* xmm5 := be(xmm5) */ "movdqa %%xmm5, (%[ctr])\n\t" /* Update CTR (mem). */ ".Ldone_ctr%=:\n\t" : : [ctr] "r" (ctr), [key] "r" (ctx->keyschenc), [addb] "r" (bige_addb) : "%esi", "cc", "memory"); asm volatile ("pxor %%xmm1, %%xmm0\n\t" /* xmm0 ^= key[0] */ "pxor %%xmm1, %%xmm2\n\t" /* xmm2 ^= key[0] */ "pxor %%xmm1, %%xmm3\n\t" /* xmm3 ^= key[0] */ "pxor %%xmm1, %%xmm4\n\t" /* xmm4 ^= key[0] */ "movdqa 0x10(%[key]), %%xmm1\n\t" aesenc_xmm1_xmm0 aesenc_xmm1_xmm2 aesenc_xmm1_xmm3 aesenc_xmm1_xmm4 "movdqa 0x20(%[key]), %%xmm1\n\t" aesenc_xmm1_xmm0 aesenc_xmm1_xmm2 aesenc_xmm1_xmm3 aesenc_xmm1_xmm4 "movdqa 0x30(%[key]), %%xmm1\n\t" aesenc_xmm1_xmm0 aesenc_xmm1_xmm2 aesenc_xmm1_xmm3 aesenc_xmm1_xmm4 "movdqa 0x40(%[key]), %%xmm1\n\t" aesenc_xmm1_xmm0 aesenc_xmm1_xmm2 aesenc_xmm1_xmm3 aesenc_xmm1_xmm4 "movdqa 0x50(%[key]), %%xmm1\n\t" aesenc_xmm1_xmm0 aesenc_xmm1_xmm2 aesenc_xmm1_xmm3 aesenc_xmm1_xmm4 "movdqa 0x60(%[key]), %%xmm1\n\t" aesenc_xmm1_xmm0 aesenc_xmm1_xmm2 aesenc_xmm1_xmm3 aesenc_xmm1_xmm4 "movdqa 0x70(%[key]), %%xmm1\n\t" aesenc_xmm1_xmm0 aesenc_xmm1_xmm2 aesenc_xmm1_xmm3 aesenc_xmm1_xmm4 "movdqa 0x80(%[key]), %%xmm1\n\t" aesenc_xmm1_xmm0 aesenc_xmm1_xmm2 aesenc_xmm1_xmm3 aesenc_xmm1_xmm4 "movdqa 0x90(%[key]), %%xmm1\n\t" aesenc_xmm1_xmm0 aesenc_xmm1_xmm2 aesenc_xmm1_xmm3 aesenc_xmm1_xmm4 "movdqa 0xa0(%[key]), %%xmm1\n\t" "cmpl $10, %[rounds]\n\t" "jz .Lenclast%=\n\t" aesenc_xmm1_xmm0 aesenc_xmm1_xmm2 aesenc_xmm1_xmm3 aesenc_xmm1_xmm4 "movdqa 0xb0(%[key]), %%xmm1\n\t" aesenc_xmm1_xmm0 aesenc_xmm1_xmm2 aesenc_xmm1_xmm3 aesenc_xmm1_xmm4 "movdqa 0xc0(%[key]), %%xmm1\n\t" "cmpl $12, %[rounds]\n\t" "jz .Lenclast%=\n\t" aesenc_xmm1_xmm0 aesenc_xmm1_xmm2 aesenc_xmm1_xmm3 aesenc_xmm1_xmm4 "movdqa 0xd0(%[key]), %%xmm1\n\t" aesenc_xmm1_xmm0 aesenc_xmm1_xmm2 aesenc_xmm1_xmm3 aesenc_xmm1_xmm4 "movdqa 0xe0(%[key]), %%xmm1\n" ".Lenclast%=:\n\t" aesenclast_xmm1_xmm0 aesenclast_xmm1_xmm2 aesenclast_xmm1_xmm3 aesenclast_xmm1_xmm4 : : [key] "r" (ctx->keyschenc), [rounds] "r" (ctx->rounds) : "cc", "memory"); asm volatile ("movdqu (%[src]), %%xmm1\n\t" /* Get block 1. */ "pxor %%xmm1, %%xmm0\n\t" /* EncCTR-1 ^= input */ "movdqu %%xmm0, (%[dst])\n\t" /* Store block 1 */ "movdqu 16(%[src]), %%xmm1\n\t" /* Get block 2. */ "pxor %%xmm1, %%xmm2\n\t" /* EncCTR-2 ^= input */ "movdqu %%xmm2, 16(%[dst])\n\t" /* Store block 2. */ "movdqu 32(%[src]), %%xmm1\n\t" /* Get block 3. */ "pxor %%xmm1, %%xmm3\n\t" /* EncCTR-3 ^= input */ "movdqu %%xmm3, 32(%[dst])\n\t" /* Store block 3. */ "movdqu 48(%[src]), %%xmm1\n\t" /* Get block 4. */ "pxor %%xmm1, %%xmm4\n\t" /* EncCTR-4 ^= input */ "movdqu %%xmm4, 48(%[dst])" /* Store block 4. */ : : [src] "r" (a), [dst] "r" (b) : "memory"); #undef aesenc_xmm1_xmm0 #undef aesenc_xmm1_xmm2 #undef aesenc_xmm1_xmm3 #undef aesenc_xmm1_xmm4 #undef aesenclast_xmm1_xmm0 #undef aesenclast_xmm1_xmm2 #undef aesenclast_xmm1_xmm3 #undef aesenclast_xmm1_xmm4 } #ifdef __x86_64__ /* Eight blocks at a time variant of do_aesni_ctr. */ static ASM_FUNC_ATTR_INLINE void do_aesni_ctr_8 (const RIJNDAEL_context *ctx, unsigned char *ctr, unsigned char *b, const unsigned char *a) { static const byte bige_addb_const[8][16] __attribute__ ((aligned (16))) = { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8 } }; const void *bige_addb = bige_addb_const; /* Register usage: [key] keyschedule xmm0 CTR-0 xmm1 temp / round key xmm2 CTR-1 xmm3 CTR-2 xmm4 CTR-3 xmm5 copy of *ctr xmm6 endian swapping mask xmm8 CTR-4 xmm9 CTR-5 xmm10 CTR-6 xmm11 CTR-7 xmm12 temp xmm13 temp xmm14 temp xmm15 temp */ asm volatile (/* detect if 8-bit carry handling is needed */ "addb $8, 15(%[ctr])\n\t" "jc .Ladd32bit%=\n\t" "movdqa (%[key]), %%xmm1\n\t" /* xmm1 := key[0] */ "movdqa 16(%[key]), %%xmm7\n\t" /* xmm7 := key[1] */ "movdqa %%xmm5, %%xmm0\n\t" /* xmm0 := CTR (xmm5) */ "movdqa %%xmm5, %%xmm2\n\t" /* xmm2 := CTR (xmm5) */ "movdqa %%xmm5, %%xmm3\n\t" /* xmm3 := CTR (xmm5) */ "movdqa %%xmm5, %%xmm4\n\t" /* xmm4 := CTR (xmm5) */ "paddb 0*16(%[addb]), %%xmm2\n\t" /* xmm2 := be(1) + CTR */ "paddb 1*16(%[addb]), %%xmm3\n\t" /* xmm3 := be(2) + CTR */ "paddb 2*16(%[addb]), %%xmm4\n\t" /* xmm4 := be(3) + CTR */ "pxor %%xmm1, %%xmm0\n\t" /* xmm0 ^= key[0] */ "pxor %%xmm1, %%xmm2\n\t" /* xmm2 ^= key[0] */ "pxor %%xmm1, %%xmm3\n\t" /* xmm3 ^= key[0] */ "pxor %%xmm1, %%xmm4\n\t" /* xmm4 ^= key[0] */ "aesenc %%xmm7, %%xmm0\n\t" "aesenc %%xmm7, %%xmm2\n\t" "aesenc %%xmm7, %%xmm3\n\t" "aesenc %%xmm7, %%xmm4\n\t" "movdqa %%xmm5, %%xmm8\n\t" /* xmm8 := CTR (xmm5) */ "movdqa %%xmm5, %%xmm9\n\t" /* xmm9 := CTR (xmm5) */ "movdqa %%xmm5, %%xmm10\n\t" /* xmm10 := CTR (xmm5) */ "movdqa %%xmm5, %%xmm11\n\t" /* xmm11 := CTR (xmm5) */ "paddb 3*16(%[addb]), %%xmm8\n\t" /* xmm8 := be(4) + CTR */ "paddb 4*16(%[addb]), %%xmm9\n\t" /* xmm9 := be(5) + CTR */ "paddb 5*16(%[addb]), %%xmm10\n\t" /* xmm10 := be(6) + CTR */ "paddb 6*16(%[addb]), %%xmm11\n\t" /* xmm11 := be(7) + CTR */ "pxor %%xmm1, %%xmm8\n\t" /* xmm8 ^= key[0] */ "pxor %%xmm1, %%xmm9\n\t" /* xmm9 ^= key[0] */ "pxor %%xmm1, %%xmm10\n\t" /* xmm10 ^= key[0] */ "pxor %%xmm1, %%xmm11\n\t" /* xmm11 ^= key[0] */ "aesenc %%xmm7, %%xmm8\n\t" "aesenc %%xmm7, %%xmm9\n\t" "aesenc %%xmm7, %%xmm10\n\t" "aesenc %%xmm7, %%xmm11\n\t" "paddb 7*16(%[addb]), %%xmm5\n\t" /* xmm5 := be(8) + CTR */ "jmp .Ldone_ctr%=\n\t" ".Ladd32bit%=:\n\t" "movdqa %%xmm5, (%[ctr])\n\t" /* Restore CTR. */ "movdqa %%xmm5, %%xmm0\n\t" /* xmm0, xmm2 := CTR (xmm5) */ "movdqa %%xmm0, %%xmm2\n\t" "pcmpeqd %%xmm1, %%xmm1\n\t" "psrldq $8, %%xmm1\n\t" /* xmm1 = -1 */ "pshufb %%xmm6, %%xmm2\n\t" /* xmm2 := le(xmm2) */ "psubq %%xmm1, %%xmm2\n\t" /* xmm2++ */ "movdqa %%xmm2, %%xmm3\n\t" /* xmm3 := xmm2 */ "psubq %%xmm1, %%xmm3\n\t" /* xmm3++ */ "movdqa %%xmm3, %%xmm4\n\t" /* xmm4 := xmm3 */ "psubq %%xmm1, %%xmm4\n\t" /* xmm4++ */ "movdqa %%xmm4, %%xmm8\n\t" /* xmm8 := xmm4 */ "psubq %%xmm1, %%xmm8\n\t" /* xmm8++ */ "movdqa %%xmm8, %%xmm9\n\t" /* xmm9 := xmm8 */ "psubq %%xmm1, %%xmm9\n\t" /* xmm9++ */ "movdqa %%xmm9, %%xmm10\n\t" /* xmm10 := xmm9 */ "psubq %%xmm1, %%xmm10\n\t" /* xmm10++ */ "movdqa %%xmm10, %%xmm11\n\t" /* xmm11 := xmm10 */ "psubq %%xmm1, %%xmm11\n\t" /* xmm11++ */ "movdqa %%xmm11, %%xmm5\n\t" /* xmm5 := xmm11 */ "psubq %%xmm1, %%xmm5\n\t" /* xmm5++ */ /* detect if 64-bit carry handling is needed */ "cmpl $0xffffffff, 8(%[ctr])\n\t" "jne .Lno_carry%=\n\t" "movl 12(%[ctr]), %%esi\n\t" "bswapl %%esi\n\t" "cmpl $0xfffffff8, %%esi\n\t" "jb .Lno_carry%=\n\t" /* no carry */ "pslldq $8, %%xmm1\n\t" /* move lower 64-bit to high */ "je .Lcarry_xmm5%=\n\t" /* esi == 0xfffffff8 */ "cmpl $0xfffffffa, %%esi\n\t" "jb .Lcarry_xmm11%=\n\t" /* esi == 0xfffffff9 */ "je .Lcarry_xmm10%=\n\t" /* esi == 0xfffffffa */ "cmpl $0xfffffffc, %%esi\n\t" "jb .Lcarry_xmm9%=\n\t" /* esi == 0xfffffffb */ "je .Lcarry_xmm8%=\n\t" /* esi == 0xfffffffc */ "cmpl $0xfffffffe, %%esi\n\t" "jb .Lcarry_xmm4%=\n\t" /* esi == 0xfffffffd */ "je .Lcarry_xmm3%=\n\t" /* esi == 0xfffffffe */ /* esi == 0xffffffff */ "psubq %%xmm1, %%xmm2\n\t" ".Lcarry_xmm3%=:\n\t" "psubq %%xmm1, %%xmm3\n\t" ".Lcarry_xmm4%=:\n\t" "psubq %%xmm1, %%xmm4\n\t" ".Lcarry_xmm8%=:\n\t" "psubq %%xmm1, %%xmm8\n\t" ".Lcarry_xmm9%=:\n\t" "psubq %%xmm1, %%xmm9\n\t" ".Lcarry_xmm10%=:\n\t" "psubq %%xmm1, %%xmm10\n\t" ".Lcarry_xmm11%=:\n\t" "psubq %%xmm1, %%xmm11\n\t" ".Lcarry_xmm5%=:\n\t" "psubq %%xmm1, %%xmm5\n\t" ".Lno_carry%=:\n\t" "movdqa (%[key]), %%xmm1\n\t" /* xmm1 := key[0] */ "movdqa 16(%[key]), %%xmm7\n\t" /* xmm7 := key[1] */ "pshufb %%xmm6, %%xmm2\n\t" /* xmm2 := be(xmm2) */ "pshufb %%xmm6, %%xmm3\n\t" /* xmm3 := be(xmm3) */ "pshufb %%xmm6, %%xmm4\n\t" /* xmm4 := be(xmm4) */ "pxor %%xmm1, %%xmm0\n\t" /* xmm0 ^= key[0] */ "pxor %%xmm1, %%xmm2\n\t" /* xmm2 ^= key[0] */ "pxor %%xmm1, %%xmm3\n\t" /* xmm3 ^= key[0] */ "pxor %%xmm1, %%xmm4\n\t" /* xmm4 ^= key[0] */ "aesenc %%xmm7, %%xmm0\n\t" "aesenc %%xmm7, %%xmm2\n\t" "aesenc %%xmm7, %%xmm3\n\t" "aesenc %%xmm7, %%xmm4\n\t" "pshufb %%xmm6, %%xmm8\n\t" /* xmm8 := be(xmm8) */ "pshufb %%xmm6, %%xmm9\n\t" /* xmm9 := be(xmm9) */ "pshufb %%xmm6, %%xmm10\n\t" /* xmm10 := be(xmm10) */ "pshufb %%xmm6, %%xmm11\n\t" /* xmm11 := be(xmm11) */ "pxor %%xmm1, %%xmm8\n\t" /* xmm8 ^= key[0] */ "pxor %%xmm1, %%xmm9\n\t" /* xmm9 ^= key[0] */ "pxor %%xmm1, %%xmm10\n\t" /* xmm10 ^= key[0] */ "pxor %%xmm1, %%xmm11\n\t" /* xmm11 ^= key[0] */ "aesenc %%xmm7, %%xmm8\n\t" "aesenc %%xmm7, %%xmm9\n\t" "aesenc %%xmm7, %%xmm10\n\t" "aesenc %%xmm7, %%xmm11\n\t" "pshufb %%xmm6, %%xmm5\n\t" /* xmm5 := be(xmm5) */ "movdqa %%xmm5, (%[ctr])\n\t" /* Update CTR (mem). */ ".align 16\n\t" ".Ldone_ctr%=:\n\t" : : [ctr] "r" (ctr), [key] "r" (ctx->keyschenc), [addb] "r" (bige_addb) : "%esi", "cc", "memory"); asm volatile ("movdqa 0x20(%[key]), %%xmm1\n\t" "movdqu 0*16(%[src]), %%xmm12\n\t" /* Get block 1. */ "movdqu 1*16(%[src]), %%xmm13\n\t" /* Get block 2. */ "movdqu 2*16(%[src]), %%xmm14\n\t" /* Get block 3. */ "movdqu 3*16(%[src]), %%xmm15\n\t" /* Get block 4. */ "movdqu 4*16(%[src]), %%xmm7\n\t" /* Get block 5. */ "aesenc %%xmm1, %%xmm0\n\t" "aesenc %%xmm1, %%xmm2\n\t" "aesenc %%xmm1, %%xmm3\n\t" "aesenc %%xmm1, %%xmm4\n\t" "aesenc %%xmm1, %%xmm8\n\t" "aesenc %%xmm1, %%xmm9\n\t" "aesenc %%xmm1, %%xmm10\n\t" "aesenc %%xmm1, %%xmm11\n\t" "cmpl $12, %[rounds]\n\t" "movdqa 0x30(%[key]), %%xmm1\n\t" "aesenc %%xmm1, %%xmm0\n\t" "aesenc %%xmm1, %%xmm2\n\t" "aesenc %%xmm1, %%xmm3\n\t" "aesenc %%xmm1, %%xmm4\n\t" "aesenc %%xmm1, %%xmm8\n\t" "aesenc %%xmm1, %%xmm9\n\t" "aesenc %%xmm1, %%xmm10\n\t" "aesenc %%xmm1, %%xmm11\n\t" "movdqa 0x40(%[key]), %%xmm1\n\t" "aesenc %%xmm1, %%xmm0\n\t" "aesenc %%xmm1, %%xmm2\n\t" "aesenc %%xmm1, %%xmm3\n\t" "aesenc %%xmm1, %%xmm4\n\t" "aesenc %%xmm1, %%xmm8\n\t" "aesenc %%xmm1, %%xmm9\n\t" "aesenc %%xmm1, %%xmm10\n\t" "aesenc %%xmm1, %%xmm11\n\t" "movdqa 0x50(%[key]), %%xmm1\n\t" "aesenc %%xmm1, %%xmm0\n\t" "aesenc %%xmm1, %%xmm2\n\t" "aesenc %%xmm1, %%xmm3\n\t" "aesenc %%xmm1, %%xmm4\n\t" "aesenc %%xmm1, %%xmm8\n\t" "aesenc %%xmm1, %%xmm9\n\t" "aesenc %%xmm1, %%xmm10\n\t" "aesenc %%xmm1, %%xmm11\n\t" "movdqa 0x60(%[key]), %%xmm1\n\t" "aesenc %%xmm1, %%xmm0\n\t" "aesenc %%xmm1, %%xmm2\n\t" "aesenc %%xmm1, %%xmm3\n\t" "aesenc %%xmm1, %%xmm4\n\t" "aesenc %%xmm1, %%xmm8\n\t" "aesenc %%xmm1, %%xmm9\n\t" "aesenc %%xmm1, %%xmm10\n\t" "aesenc %%xmm1, %%xmm11\n\t" "movdqa 0x70(%[key]), %%xmm1\n\t" "aesenc %%xmm1, %%xmm0\n\t" "aesenc %%xmm1, %%xmm2\n\t" "aesenc %%xmm1, %%xmm3\n\t" "aesenc %%xmm1, %%xmm4\n\t" "aesenc %%xmm1, %%xmm8\n\t" "aesenc %%xmm1, %%xmm9\n\t" "aesenc %%xmm1, %%xmm10\n\t" "aesenc %%xmm1, %%xmm11\n\t" "movdqa 0x80(%[key]), %%xmm1\n\t" "aesenc %%xmm1, %%xmm0\n\t" "aesenc %%xmm1, %%xmm2\n\t" "aesenc %%xmm1, %%xmm3\n\t" "aesenc %%xmm1, %%xmm4\n\t" "aesenc %%xmm1, %%xmm8\n\t" "aesenc %%xmm1, %%xmm9\n\t" "aesenc %%xmm1, %%xmm10\n\t" "aesenc %%xmm1, %%xmm11\n\t" "movdqa 0x90(%[key]), %%xmm1\n\t" "aesenc %%xmm1, %%xmm0\n\t" "aesenc %%xmm1, %%xmm2\n\t" "aesenc %%xmm1, %%xmm3\n\t" "aesenc %%xmm1, %%xmm4\n\t" "aesenc %%xmm1, %%xmm8\n\t" "aesenc %%xmm1, %%xmm9\n\t" "aesenc %%xmm1, %%xmm10\n\t" "aesenc %%xmm1, %%xmm11\n\t" "movdqa 0xa0(%[key]), %%xmm1\n\t" "jb .Lenclast%=\n\t" "aesenc %%xmm1, %%xmm0\n\t" "aesenc %%xmm1, %%xmm2\n\t" "aesenc %%xmm1, %%xmm3\n\t" "aesenc %%xmm1, %%xmm4\n\t" "aesenc %%xmm1, %%xmm8\n\t" "aesenc %%xmm1, %%xmm9\n\t" "aesenc %%xmm1, %%xmm10\n\t" "aesenc %%xmm1, %%xmm11\n\t" "movdqa 0xb0(%[key]), %%xmm1\n\t" "aesenc %%xmm1, %%xmm0\n\t" "aesenc %%xmm1, %%xmm2\n\t" "aesenc %%xmm1, %%xmm3\n\t" "aesenc %%xmm1, %%xmm4\n\t" "aesenc %%xmm1, %%xmm8\n\t" "aesenc %%xmm1, %%xmm9\n\t" "aesenc %%xmm1, %%xmm10\n\t" "aesenc %%xmm1, %%xmm11\n\t" "movdqa 0xc0(%[key]), %%xmm1\n\t" "je .Lenclast%=\n\t" "aesenc %%xmm1, %%xmm0\n\t" "aesenc %%xmm1, %%xmm2\n\t" "aesenc %%xmm1, %%xmm3\n\t" "aesenc %%xmm1, %%xmm4\n\t" "aesenc %%xmm1, %%xmm8\n\t" "aesenc %%xmm1, %%xmm9\n\t" "aesenc %%xmm1, %%xmm10\n\t" "aesenc %%xmm1, %%xmm11\n\t" "movdqa 0xd0(%[key]), %%xmm1\n\t" "aesenc %%xmm1, %%xmm0\n\t" "aesenc %%xmm1, %%xmm2\n\t" "aesenc %%xmm1, %%xmm3\n\t" "aesenc %%xmm1, %%xmm4\n\t" "aesenc %%xmm1, %%xmm8\n\t" "aesenc %%xmm1, %%xmm9\n\t" "aesenc %%xmm1, %%xmm10\n\t" "aesenc %%xmm1, %%xmm11\n\t" "movdqa 0xe0(%[key]), %%xmm1\n" ".Lenclast%=:\n\t" : : [key] "r" (ctx->keyschenc), [rounds] "r" (ctx->rounds), [src] "r" (a) : "cc", "memory"); asm volatile ("pxor %%xmm1, %%xmm12\n\t" /* block1 ^= lastkey */ "pxor %%xmm1, %%xmm13\n\t" /* block2 ^= lastkey */ "pxor %%xmm1, %%xmm14\n\t" /* block3 ^= lastkey */ "pxor %%xmm1, %%xmm15\n\t" /* block4 ^= lastkey */ "aesenclast %%xmm12, %%xmm0\n\t" "aesenclast %%xmm13, %%xmm2\n\t" "aesenclast %%xmm14, %%xmm3\n\t" "aesenclast %%xmm15, %%xmm4\n\t" "movdqu 5*16(%[src]), %%xmm12\n\t" /* Get block 6. */ "movdqu 6*16(%[src]), %%xmm13\n\t" /* Get block 7. */ "movdqu 7*16(%[src]), %%xmm14\n\t" /* Get block 8. */ "movdqu %%xmm0, 0*16(%[dst])\n\t" /* Store block 1. */ "movdqu %%xmm2, 1*16(%[dst])\n\t" /* Store block 2. */ "movdqu %%xmm3, 2*16(%[dst])\n\t" /* Store block 3. */ "movdqu %%xmm4, 3*16(%[dst])\n\t" /* Store block 4. */ "pxor %%xmm1, %%xmm7\n\t" /* block5 ^= lastkey */ "pxor %%xmm1, %%xmm12\n\t" /* block6 ^= lastkey */ "pxor %%xmm1, %%xmm13\n\t" /* block7 ^= lastkey */ "pxor %%xmm1, %%xmm14\n\t" /* block8 ^= lastkey */ "aesenclast %%xmm7, %%xmm8\n\t" "aesenclast %%xmm12, %%xmm9\n\t" "aesenclast %%xmm13, %%xmm10\n\t" "aesenclast %%xmm14, %%xmm11\n\t" "movdqu %%xmm8, 4*16(%[dst])\n\t" /* Store block 8. */ "movdqu %%xmm9, 5*16(%[dst])\n\t" /* Store block 9. */ "movdqu %%xmm10, 6*16(%[dst])\n\t" /* Store block 10. */ "movdqu %%xmm11, 7*16(%[dst])\n\t" /* Store block 11. */ : : [src] "r" (a), [dst] "r" (b) : "memory"); } #endif /* __x86_64__ */ unsigned int ASM_FUNC_ATTR _gcry_aes_aesni_encrypt (const RIJNDAEL_context *ctx, unsigned char *dst, const unsigned char *src) { aesni_prepare (); asm volatile ("movdqu %[src], %%xmm0\n\t" : : [src] "m" (*src) : "memory" ); do_aesni_enc (ctx); asm volatile ("movdqu %%xmm0, %[dst]\n\t" : [dst] "=m" (*dst) : : "memory" ); aesni_cleanup (); return 0; } void ASM_FUNC_ATTR _gcry_aes_aesni_cfb_enc (RIJNDAEL_context *ctx, unsigned char *iv, unsigned char *outbuf, const unsigned char *inbuf, size_t nblocks) { 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 (); } +void ASM_FUNC_ATTR +_gcry_aes_aesni_ctr32le_enc (RIJNDAEL_context *ctx, unsigned char *ctr, + unsigned char *outbuf, const unsigned char *inbuf, + size_t nblocks) +{ + static const byte le_addd_const[8][16] __attribute__ ((aligned (16))) = + { + { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } + }; + aesni_prepare_2_7_variable; + + aesni_prepare (); + aesni_prepare_2_7(); + + asm volatile ("movdqa %[ctr], %%xmm5\n\t" /* Preload CTR */ + : /* No output */ + : [ctr] "m" (*ctr) + : "memory"); + +#ifdef __x86_64__ + if (nblocks >= 8) + { + aesni_prepare_8_15_variable; + + aesni_prepare_8_15(); + + for ( ;nblocks >= 8 ; nblocks -= 8 ) + { + asm volatile + ("movdqa (%[key]), %%xmm0\n\t" + + "movdqa %%xmm5, %%xmm1\n\t" /* load input blocks */ + "movdqa %%xmm5, %%xmm2\n\t" + "movdqa %%xmm5, %%xmm3\n\t" + "movdqa %%xmm5, %%xmm4\n\t" + "movdqa %%xmm5, %%xmm8\n\t" + "movdqa %%xmm5, %%xmm9\n\t" + "movdqa %%xmm5, %%xmm10\n\t" + "movdqa %%xmm5, %%xmm11\n\t" + + "paddd 0*16(%[addd]), %%xmm2\n\t" + "paddd 1*16(%[addd]), %%xmm3\n\t" + "paddd 2*16(%[addd]), %%xmm4\n\t" + "paddd 3*16(%[addd]), %%xmm8\n\t" + "paddd 4*16(%[addd]), %%xmm9\n\t" + "paddd 5*16(%[addd]), %%xmm10\n\t" + "paddd 6*16(%[addd]), %%xmm11\n\t" + + "pxor %%xmm0, %%xmm1\n\t" /* xmm1 ^= key[0] */ + "pxor %%xmm0, %%xmm2\n\t" /* xmm2 ^= key[0] */ + "pxor %%xmm0, %%xmm3\n\t" /* xmm3 ^= key[0] */ + "pxor %%xmm0, %%xmm4\n\t" /* xmm4 ^= key[0] */ + "pxor %%xmm0, %%xmm8\n\t" /* xmm8 ^= key[0] */ + "pxor %%xmm0, %%xmm9\n\t" /* xmm9 ^= key[0] */ + "pxor %%xmm0, %%xmm10\n\t" /* xmm10 ^= key[0] */ + "pxor %%xmm0, %%xmm11\n\t" /* xmm11 ^= key[0] */ + + "movdqu 0*16(%[inbuf]), %%xmm6\n\t" + "movdqu 1*16(%[inbuf]), %%xmm7\n\t" + "movdqu 2*16(%[inbuf]), %%xmm12\n\t" + "movdqu 3*16(%[inbuf]), %%xmm13\n\t" + "movdqu 4*16(%[inbuf]), %%xmm14\n\t" + "movdqu 5*16(%[inbuf]), %%xmm15\n\t" + + "paddd 7*16(%[addd]), %%xmm5\n\t" + : /* No output */ + : [addd] "r" (&le_addd_const[0][0]), + [inbuf] "r" (inbuf), + [key] "r" (ctx->keyschenc) + : "memory"); + + do_aesni_enc_vec8 (ctx); + + asm volatile + ("pxor %%xmm0, %%xmm6\n\t" + "pxor %%xmm0, %%xmm7\n\t" + "pxor %%xmm0, %%xmm12\n\t" + "pxor %%xmm0, %%xmm13\n\t" + "pxor %%xmm0, %%xmm14\n\t" + "pxor %%xmm0, %%xmm15\n\t" + "aesenclast %%xmm6, %%xmm1\n\t" + "aesenclast %%xmm7, %%xmm2\n\t" + "movdqu 6*16(%[inbuf]), %%xmm6\n\t" + "movdqu 7*16(%[inbuf]), %%xmm7\n\t" + "aesenclast %%xmm12, %%xmm3\n\t" + "aesenclast %%xmm13, %%xmm4\n\t" + "pxor %%xmm0, %%xmm6\n\t" + "pxor %%xmm0, %%xmm7\n\t" + "aesenclast %%xmm14, %%xmm8\n\t" + "aesenclast %%xmm15, %%xmm9\n\t" + "aesenclast %%xmm6, %%xmm10\n\t" + "aesenclast %%xmm7, %%xmm11\n\t" + "movdqu %%xmm1, 0*16(%[outbuf])\n\t" + "movdqu %%xmm2, 1*16(%[outbuf])\n\t" + "movdqu %%xmm3, 2*16(%[outbuf])\n\t" + "movdqu %%xmm4, 3*16(%[outbuf])\n\t" + "movdqu %%xmm8, 4*16(%[outbuf])\n\t" + "movdqu %%xmm9, 5*16(%[outbuf])\n\t" + "movdqu %%xmm10, 6*16(%[outbuf])\n\t" + "movdqu %%xmm11, 7*16(%[outbuf])\n\t" + : /* No output */ + : [inbuf] "r" (inbuf), + [outbuf] "r" (outbuf) + : "memory"); + + outbuf += 8*BLOCKSIZE; + inbuf += 8*BLOCKSIZE; + } + + aesni_cleanup_8_15(); + } +#endif + + for ( ;nblocks >= 4 ; nblocks -= 4 ) + { + asm volatile + ("movdqa %%xmm5, %%xmm1\n\t" /* load input blocks */ + "movdqa %%xmm5, %%xmm2\n\t" + "movdqa %%xmm5, %%xmm3\n\t" + "movdqa %%xmm5, %%xmm4\n\t" + "paddd 0*16(%[addd]), %%xmm2\n\t" + "paddd 1*16(%[addd]), %%xmm3\n\t" + "paddd 2*16(%[addd]), %%xmm4\n\t" + "paddd 3*16(%[addd]), %%xmm5\n\t" + "movdqu 0*16(%[inbuf]), %%xmm6\n\t" + "movdqu 1*16(%[inbuf]), %%xmm7\n\t" + : /* No output */ + : [addd] "r" (&le_addd_const[0][0]), + [inbuf] "r" (inbuf) + : "memory"); + + do_aesni_enc_vec4 (ctx); + + asm volatile + ("pxor %%xmm6, %%xmm1\n\t" + "pxor %%xmm7, %%xmm2\n\t" + "movdqu 2*16(%[inbuf]), %%xmm6\n\t" + "movdqu 3*16(%[inbuf]), %%xmm7\n\t" + "movdqu %%xmm1, 0*16(%[outbuf])\n\t" + "movdqu %%xmm2, 1*16(%[outbuf])\n\t" + "pxor %%xmm6, %%xmm3\n\t" + "pxor %%xmm7, %%xmm4\n\t" + "movdqu %%xmm3, 2*16(%[outbuf])\n\t" + "movdqu %%xmm4, 3*16(%[outbuf])\n\t" + : /* No output */ + : [inbuf] "r" (inbuf), + [outbuf] "r" (outbuf) + : "memory"); + + outbuf += 4*BLOCKSIZE; + inbuf += 4*BLOCKSIZE; + } + + for ( ;nblocks; nblocks-- ) + { + asm volatile ("movdqa %%xmm5, %%xmm0\n\t" + "paddd %[add_one], %%xmm5\n\t" + "movdqu %[inbuf], %%xmm6\n\t" + : + : [add_one] "m" (*le_addd_const[0]), + [inbuf] "m" (*inbuf) + : "memory" ); + + do_aesni_enc (ctx); + + asm volatile ("pxor %%xmm0, %%xmm6\n\t" + "movdqu %%xmm6, %[outbuf]\n\t" + : [outbuf] "=m" (*outbuf) + : + : "memory" ); + + outbuf += BLOCKSIZE; + inbuf += BLOCKSIZE; + } + + asm volatile ("movdqa %%xmm5, %[ctr]\n\t" + : [ctr] "=m" (*ctr) + : + : "memory" ); + + aesni_cleanup (); + aesni_cleanup_2_7 (); +} + + unsigned int ASM_FUNC_ATTR _gcry_aes_aesni_decrypt (const RIJNDAEL_context *ctx, unsigned char *dst, const unsigned char *src) { aesni_prepare (); asm volatile ("movdqu %[src], %%xmm0\n\t" : : [src] "m" (*src) : "memory" ); do_aesni_dec (ctx); asm volatile ("movdqu %%xmm0, %[dst]\n\t" : [dst] "=m" (*dst) : : "memory" ); aesni_cleanup (); return 0; } void ASM_FUNC_ATTR _gcry_aes_aesni_cfb_dec (RIJNDAEL_context *ctx, unsigned char *iv, unsigned char *outbuf, const unsigned char *inbuf, size_t nblocks) { aesni_prepare_2_7_variable; aesni_prepare (); aesni_prepare_2_7(); asm volatile ("movdqu %[iv], %%xmm6\n\t" : /* No output */ : [iv] "m" (*iv) : "memory" ); /* CFB decryption can be parallelized */ #ifdef __x86_64__ if (nblocks >= 8) { aesni_prepare_8_15_variable; aesni_prepare_8_15(); for ( ;nblocks >= 8; nblocks -= 8) { asm volatile ("movdqa (%[key]), %%xmm0\n\t" "movdqu %%xmm6, %%xmm1\n\t" /* load input blocks */ "movdqu 0*16(%[inbuf]), %%xmm2\n\t" "movdqu 1*16(%[inbuf]), %%xmm3\n\t" "movdqu 2*16(%[inbuf]), %%xmm4\n\t" "movdqu 3*16(%[inbuf]), %%xmm8\n\t" "movdqu 4*16(%[inbuf]), %%xmm9\n\t" "movdqu 5*16(%[inbuf]), %%xmm10\n\t" "movdqu 6*16(%[inbuf]), %%xmm11\n\t" "movdqu 7*16(%[inbuf]), %%xmm6\n\t" /* update IV */ "movdqa %%xmm2, %%xmm12\n\t" "movdqa %%xmm3, %%xmm13\n\t" "movdqa %%xmm4, %%xmm14\n\t" "movdqa %%xmm8, %%xmm15\n\t" "pxor %%xmm0, %%xmm1\n\t" /* xmm1 ^= key[0] */ "pxor %%xmm0, %%xmm2\n\t" /* xmm2 ^= key[0] */ "pxor %%xmm0, %%xmm3\n\t" /* xmm3 ^= key[0] */ "pxor %%xmm0, %%xmm4\n\t" /* xmm4 ^= key[0] */ "pxor %%xmm0, %%xmm8\n\t" /* xmm8 ^= key[0] */ "pxor %%xmm0, %%xmm9\n\t" /* xmm9 ^= key[0] */ "pxor %%xmm0, %%xmm10\n\t" /* xmm10 ^= key[0] */ "pxor %%xmm0, %%xmm11\n\t" /* xmm11 ^= key[0] */ : /* No output */ : [inbuf] "r" (inbuf), [key] "r" (ctx->keyschenc) : "memory"); do_aesni_enc_vec8 (ctx); asm volatile ( "pxor %%xmm0, %%xmm12\n\t" "pxor %%xmm0, %%xmm13\n\t" "pxor %%xmm0, %%xmm14\n\t" "pxor %%xmm0, %%xmm15\n\t" "aesenclast %%xmm12, %%xmm1\n\t" "aesenclast %%xmm13, %%xmm2\n\t" "aesenclast %%xmm14, %%xmm3\n\t" "aesenclast %%xmm15, %%xmm4\n\t" "movdqu 4*16(%[inbuf]), %%xmm12\n\t" "movdqu 5*16(%[inbuf]), %%xmm13\n\t" "movdqu 6*16(%[inbuf]), %%xmm14\n\t" "movdqu 7*16(%[inbuf]), %%xmm15\n\t" "pxor %%xmm0, %%xmm12\n\t" "pxor %%xmm0, %%xmm13\n\t" "pxor %%xmm0, %%xmm14\n\t" "pxor %%xmm0, %%xmm15\n\t" "aesenclast %%xmm12, %%xmm8\n\t" "aesenclast %%xmm13, %%xmm9\n\t" "aesenclast %%xmm14, %%xmm10\n\t" "aesenclast %%xmm15, %%xmm11\n\t" "movdqu %%xmm1, 0*16(%[outbuf])\n\t" "movdqu %%xmm2, 1*16(%[outbuf])\n\t" "movdqu %%xmm3, 2*16(%[outbuf])\n\t" "movdqu %%xmm4, 3*16(%[outbuf])\n\t" "movdqu %%xmm8, 4*16(%[outbuf])\n\t" "movdqu %%xmm9, 5*16(%[outbuf])\n\t" "movdqu %%xmm10, 6*16(%[outbuf])\n\t" "movdqu %%xmm11, 7*16(%[outbuf])\n\t" : /* No output */ : [inbuf] "r" (inbuf), [outbuf] "r" (outbuf) : "memory"); outbuf += 8*BLOCKSIZE; inbuf += 8*BLOCKSIZE; } aesni_cleanup_8_15(); } #endif for ( ;nblocks >= 4; nblocks -= 4) { asm volatile ("movdqu %%xmm6, %%xmm1\n\t" /* load input blocks */ "movdqu 0*16(%[inbuf]), %%xmm2\n\t" "movdqu 1*16(%[inbuf]), %%xmm3\n\t" "movdqu 2*16(%[inbuf]), %%xmm4\n\t" "movdqu 3*16(%[inbuf]), %%xmm6\n\t" /* update IV */ : /* No output */ : [inbuf] "r" (inbuf) : "memory"); do_aesni_enc_vec4 (ctx); asm volatile ("movdqu 0*16(%[inbuf]), %%xmm5\n\t" "pxor %%xmm5, %%xmm1\n\t" "movdqu %%xmm1, 0*16(%[outbuf])\n\t" "movdqu 1*16(%[inbuf]), %%xmm5\n\t" "pxor %%xmm5, %%xmm2\n\t" "movdqu %%xmm2, 1*16(%[outbuf])\n\t" "movdqu 2*16(%[inbuf]), %%xmm5\n\t" "pxor %%xmm5, %%xmm3\n\t" "movdqu %%xmm3, 2*16(%[outbuf])\n\t" "movdqu 3*16(%[inbuf]), %%xmm5\n\t" "pxor %%xmm5, %%xmm4\n\t" "movdqu %%xmm4, 3*16(%[outbuf])\n\t" : /* No output */ : [inbuf] "r" (inbuf), [outbuf] "r" (outbuf) : "memory"); outbuf += 4*BLOCKSIZE; inbuf += 4*BLOCKSIZE; } asm volatile ("movdqu %%xmm6, %%xmm0\n\t" ::: "cc"); for ( ;nblocks; nblocks-- ) { do_aesni_enc (ctx); asm volatile ("movdqa %%xmm0, %%xmm6\n\t" "movdqu %[inbuf], %%xmm0\n\t" "pxor %%xmm0, %%xmm6\n\t" "movdqu %%xmm6, %[outbuf]\n\t" : [outbuf] "=m" (*outbuf) : [inbuf] "m" (*inbuf) : "memory" ); outbuf += BLOCKSIZE; inbuf += BLOCKSIZE; } asm volatile ("movdqu %%xmm0, %[iv]\n\t" : [iv] "=m" (*iv) : : "memory" ); aesni_cleanup (); aesni_cleanup_2_7 (); } void ASM_FUNC_ATTR _gcry_aes_aesni_cbc_dec (RIJNDAEL_context *ctx, unsigned char *iv, unsigned char *outbuf, const unsigned char *inbuf, size_t nblocks) { aesni_prepare_2_7_variable; aesni_prepare (); aesni_prepare_2_7(); if ( !ctx->decryption_prepared ) { do_aesni_prepare_decryption ( ctx ); ctx->decryption_prepared = 1; } asm volatile ("movdqu %[iv], %%xmm5\n\t" /* use xmm5 as fast IV storage */ : /* No output */ : [iv] "m" (*iv) : "memory"); #ifdef __x86_64__ if (nblocks >= 8) { aesni_prepare_8_15_variable; aesni_prepare_8_15(); for ( ;nblocks >= 8 ; nblocks -= 8 ) { asm volatile ("movdqa (%[key]), %%xmm0\n\t" "movdqu 0*16(%[inbuf]), %%xmm1\n\t" /* load input blocks */ "movdqu 1*16(%[inbuf]), %%xmm2\n\t" "movdqu 2*16(%[inbuf]), %%xmm3\n\t" "movdqu 3*16(%[inbuf]), %%xmm4\n\t" "movdqu 4*16(%[inbuf]), %%xmm8\n\t" "movdqu 5*16(%[inbuf]), %%xmm9\n\t" "movdqu 6*16(%[inbuf]), %%xmm10\n\t" "movdqu 7*16(%[inbuf]), %%xmm11\n\t" "movdqa %%xmm1, %%xmm12\n\t" "movdqa %%xmm2, %%xmm13\n\t" "movdqa %%xmm3, %%xmm14\n\t" "movdqa %%xmm4, %%xmm15\n\t" "pxor %%xmm0, %%xmm1\n\t" /* xmm1 ^= key[0] */ "pxor %%xmm0, %%xmm2\n\t" /* xmm2 ^= key[0] */ "pxor %%xmm0, %%xmm3\n\t" /* xmm3 ^= key[0] */ "pxor %%xmm0, %%xmm4\n\t" /* xmm4 ^= key[0] */ "pxor %%xmm0, %%xmm8\n\t" /* xmm8 ^= key[0] */ "pxor %%xmm0, %%xmm9\n\t" /* xmm9 ^= key[0] */ "pxor %%xmm0, %%xmm10\n\t" /* xmm10 ^= key[0] */ "pxor %%xmm0, %%xmm11\n\t" /* xmm11 ^= key[0] */ : /* No output */ : [inbuf] "r" (inbuf), [key] "r" (ctx->keyschdec) : "memory"); do_aesni_dec_vec8 (ctx); asm volatile ( "pxor %%xmm0, %%xmm5\n\t" /* xor IV with key */ "pxor %%xmm0, %%xmm12\n\t" /* xor IV with key */ "pxor %%xmm0, %%xmm13\n\t" /* xor IV with key */ "pxor %%xmm0, %%xmm14\n\t" /* xor IV with key */ "pxor %%xmm0, %%xmm15\n\t" /* xor IV with key */ "aesdeclast %%xmm5, %%xmm1\n\t" "aesdeclast %%xmm12, %%xmm2\n\t" "aesdeclast %%xmm13, %%xmm3\n\t" "aesdeclast %%xmm14, %%xmm4\n\t" "movdqu 4*16(%[inbuf]), %%xmm12\n\t" "movdqu 5*16(%[inbuf]), %%xmm13\n\t" "movdqu 6*16(%[inbuf]), %%xmm14\n\t" "movdqu 7*16(%[inbuf]), %%xmm5\n\t" "pxor %%xmm0, %%xmm12\n\t" /* xor IV with key */ "pxor %%xmm0, %%xmm13\n\t" /* xor IV with key */ "pxor %%xmm0, %%xmm14\n\t" /* xor IV with key */ "aesdeclast %%xmm15, %%xmm8\n\t" "aesdeclast %%xmm12, %%xmm9\n\t" "aesdeclast %%xmm13, %%xmm10\n\t" "aesdeclast %%xmm14, %%xmm11\n\t" "movdqu %%xmm1, 0*16(%[outbuf])\n\t" "movdqu %%xmm2, 1*16(%[outbuf])\n\t" "movdqu %%xmm3, 2*16(%[outbuf])\n\t" "movdqu %%xmm4, 3*16(%[outbuf])\n\t" "movdqu %%xmm8, 4*16(%[outbuf])\n\t" "movdqu %%xmm9, 5*16(%[outbuf])\n\t" "movdqu %%xmm10, 6*16(%[outbuf])\n\t" "movdqu %%xmm11, 7*16(%[outbuf])\n\t" : /* No output */ : [inbuf] "r" (inbuf), [outbuf] "r" (outbuf) : "memory"); outbuf += 8*BLOCKSIZE; inbuf += 8*BLOCKSIZE; } aesni_cleanup_8_15(); } #endif for ( ;nblocks >= 4 ; nblocks -= 4 ) { asm volatile ("movdqu 0*16(%[inbuf]), %%xmm1\n\t" /* load input blocks */ "movdqu 1*16(%[inbuf]), %%xmm2\n\t" "movdqu 2*16(%[inbuf]), %%xmm3\n\t" "movdqu 3*16(%[inbuf]), %%xmm4\n\t" : /* No output */ : [inbuf] "r" (inbuf) : "memory"); do_aesni_dec_vec4 (ctx); asm volatile ("pxor %%xmm5, %%xmm1\n\t" /* xor IV with output */ "movdqu 0*16(%[inbuf]), %%xmm5\n\t" /* load new IV */ "movdqu %%xmm1, 0*16(%[outbuf])\n\t" "pxor %%xmm5, %%xmm2\n\t" /* xor IV with output */ "movdqu 1*16(%[inbuf]), %%xmm5\n\t" /* load new IV */ "movdqu %%xmm2, 1*16(%[outbuf])\n\t" "pxor %%xmm5, %%xmm3\n\t" /* xor IV with output */ "movdqu 2*16(%[inbuf]), %%xmm5\n\t" /* load new IV */ "movdqu %%xmm3, 2*16(%[outbuf])\n\t" "pxor %%xmm5, %%xmm4\n\t" /* xor IV with output */ "movdqu 3*16(%[inbuf]), %%xmm5\n\t" /* load new IV */ "movdqu %%xmm4, 3*16(%[outbuf])\n\t" : /* No output */ : [inbuf] "r" (inbuf), [outbuf] "r" (outbuf) : "memory"); outbuf += 4*BLOCKSIZE; inbuf += 4*BLOCKSIZE; } for ( ;nblocks; nblocks-- ) { asm volatile ("movdqu %[inbuf], %%xmm0\n\t" "movdqa %%xmm0, %%xmm2\n\t" /* use xmm2 as savebuf */ : /* No output */ : [inbuf] "m" (*inbuf) : "memory"); /* uses only xmm0 and xmm1 */ do_aesni_dec (ctx); asm volatile ("pxor %%xmm5, %%xmm0\n\t" /* xor IV with output */ "movdqu %%xmm0, %[outbuf]\n\t" "movdqu %%xmm2, %%xmm5\n\t" /* store savebuf as new IV */ : [outbuf] "=m" (*outbuf) : : "memory"); outbuf += BLOCKSIZE; inbuf += BLOCKSIZE; } asm volatile ("movdqu %%xmm5, %[iv]\n\t" /* store IV */ : /* No output */ : [iv] "m" (*iv) : "memory"); aesni_cleanup (); aesni_cleanup_2_7 (); } static ASM_FUNC_ATTR_INLINE void aesni_ocb_checksum (gcry_cipher_hd_t c, const unsigned char *plaintext, size_t nblocks) { RIJNDAEL_context *ctx = (void *)&c->context.c; /* Calculate checksum */ asm volatile ("movdqu %[checksum], %%xmm6\n\t" "pxor %%xmm1, %%xmm1\n\t" "pxor %%xmm2, %%xmm2\n\t" "pxor %%xmm3, %%xmm3\n\t" : :[checksum] "m" (*c->u_ctr.ctr) : "memory" ); if (0) {} #if defined(HAVE_GCC_INLINE_ASM_AVX2) else if (nblocks >= 16 && ctx->use_avx2) { /* Use wider 256-bit registers for fast xoring of plaintext. */ asm volatile ("vzeroupper\n\t" "vpxor %%xmm0, %%xmm0, %%xmm0\n\t" "vpxor %%xmm4, %%xmm4, %%xmm4\n\t" "vpxor %%xmm5, %%xmm5, %%xmm5\n\t" "vpxor %%xmm7, %%xmm7, %%xmm7\n\t" : : : "memory"); for (;nblocks >= 16; nblocks -= 16) { asm volatile ("vpxor %[ptr0], %%ymm6, %%ymm6\n\t" "vpxor %[ptr1], %%ymm1, %%ymm1\n\t" "vpxor %[ptr2], %%ymm2, %%ymm2\n\t" "vpxor %[ptr3], %%ymm3, %%ymm3\n\t" : : [ptr0] "m" (*(plaintext + 0 * BLOCKSIZE * 2)), [ptr1] "m" (*(plaintext + 1 * BLOCKSIZE * 2)), [ptr2] "m" (*(plaintext + 2 * BLOCKSIZE * 2)), [ptr3] "m" (*(plaintext + 3 * BLOCKSIZE * 2)) : "memory" ); asm volatile ("vpxor %[ptr4], %%ymm0, %%ymm0\n\t" "vpxor %[ptr5], %%ymm4, %%ymm4\n\t" "vpxor %[ptr6], %%ymm5, %%ymm5\n\t" "vpxor %[ptr7], %%ymm7, %%ymm7\n\t" : : [ptr4] "m" (*(plaintext + 4 * BLOCKSIZE * 2)), [ptr5] "m" (*(plaintext + 5 * BLOCKSIZE * 2)), [ptr6] "m" (*(plaintext + 6 * BLOCKSIZE * 2)), [ptr7] "m" (*(plaintext + 7 * BLOCKSIZE * 2)) : "memory" ); plaintext += BLOCKSIZE * 16; } asm volatile ("vpxor %%ymm0, %%ymm6, %%ymm6\n\t" "vpxor %%ymm4, %%ymm1, %%ymm1\n\t" "vpxor %%ymm5, %%ymm2, %%ymm2\n\t" "vpxor %%ymm7, %%ymm3, %%ymm3\n\t" "vextracti128 $1, %%ymm6, %%xmm0\n\t" "vextracti128 $1, %%ymm1, %%xmm4\n\t" "vextracti128 $1, %%ymm2, %%xmm5\n\t" "vextracti128 $1, %%ymm3, %%xmm7\n\t" "vpxor %%xmm0, %%xmm6, %%xmm6\n\t" "vpxor %%xmm4, %%xmm1, %%xmm1\n\t" "vpxor %%xmm5, %%xmm2, %%xmm2\n\t" "vpxor %%xmm7, %%xmm3, %%xmm3\n\t" "vzeroupper\n\t" : : : "memory" ); } #endif #if defined(HAVE_GCC_INLINE_ASM_AVX) else if (nblocks >= 16 && ctx->use_avx) { /* Same as AVX2, except using 256-bit floating point instructions. */ asm volatile ("vzeroupper\n\t" "vxorpd %%xmm0, %%xmm0, %%xmm0\n\t" "vxorpd %%xmm4, %%xmm4, %%xmm4\n\t" "vxorpd %%xmm5, %%xmm5, %%xmm5\n\t" "vxorpd %%xmm7, %%xmm7, %%xmm7\n\t" : : : "memory"); for (;nblocks >= 16; nblocks -= 16) { asm volatile ("vxorpd %[ptr0], %%ymm6, %%ymm6\n\t" "vxorpd %[ptr1], %%ymm1, %%ymm1\n\t" "vxorpd %[ptr2], %%ymm2, %%ymm2\n\t" "vxorpd %[ptr3], %%ymm3, %%ymm3\n\t" : : [ptr0] "m" (*(plaintext + 0 * BLOCKSIZE * 2)), [ptr1] "m" (*(plaintext + 1 * BLOCKSIZE * 2)), [ptr2] "m" (*(plaintext + 2 * BLOCKSIZE * 2)), [ptr3] "m" (*(plaintext + 3 * BLOCKSIZE * 2)) : "memory" ); asm volatile ("vxorpd %[ptr4], %%ymm0, %%ymm0\n\t" "vxorpd %[ptr5], %%ymm4, %%ymm4\n\t" "vxorpd %[ptr6], %%ymm5, %%ymm5\n\t" "vxorpd %[ptr7], %%ymm7, %%ymm7\n\t" : : [ptr4] "m" (*(plaintext + 4 * BLOCKSIZE * 2)), [ptr5] "m" (*(plaintext + 5 * BLOCKSIZE * 2)), [ptr6] "m" (*(plaintext + 6 * BLOCKSIZE * 2)), [ptr7] "m" (*(plaintext + 7 * BLOCKSIZE * 2)) : "memory" ); plaintext += BLOCKSIZE * 16; } asm volatile ("vxorpd %%ymm0, %%ymm6, %%ymm6\n\t" "vxorpd %%ymm4, %%ymm1, %%ymm1\n\t" "vxorpd %%ymm5, %%ymm2, %%ymm2\n\t" "vxorpd %%ymm7, %%ymm3, %%ymm3\n\t" "vextractf128 $1, %%ymm6, %%xmm0\n\t" "vextractf128 $1, %%ymm1, %%xmm4\n\t" "vextractf128 $1, %%ymm2, %%xmm5\n\t" "vextractf128 $1, %%ymm3, %%xmm7\n\t" "vxorpd %%xmm0, %%xmm6, %%xmm6\n\t" "vxorpd %%xmm4, %%xmm1, %%xmm1\n\t" "vxorpd %%xmm5, %%xmm2, %%xmm2\n\t" "vxorpd %%xmm7, %%xmm3, %%xmm3\n\t" "vzeroupper\n\t" : : : "memory" ); } #endif for (;nblocks >= 4; nblocks -= 4) { asm volatile ("movdqu %[ptr0], %%xmm0\n\t" "movdqu %[ptr1], %%xmm4\n\t" "movdqu %[ptr2], %%xmm5\n\t" "movdqu %[ptr3], %%xmm7\n\t" "pxor %%xmm0, %%xmm6\n\t" "pxor %%xmm4, %%xmm1\n\t" "pxor %%xmm5, %%xmm2\n\t" "pxor %%xmm7, %%xmm3\n\t" : : [ptr0] "m" (*(plaintext + 0 * BLOCKSIZE)), [ptr1] "m" (*(plaintext + 1 * BLOCKSIZE)), [ptr2] "m" (*(plaintext + 2 * BLOCKSIZE)), [ptr3] "m" (*(plaintext + 3 * BLOCKSIZE)) : "memory" ); plaintext += BLOCKSIZE * 4; } for (;nblocks >= 1; nblocks -= 1) { asm volatile ("movdqu %[ptr0], %%xmm0\n\t" "pxor %%xmm0, %%xmm6\n\t" : : [ptr0] "m" (*(plaintext + 0 * BLOCKSIZE)) : "memory" ); plaintext += BLOCKSIZE; } asm volatile ("pxor %%xmm1, %%xmm6\n\t" "pxor %%xmm2, %%xmm6\n\t" "pxor %%xmm3, %%xmm6\n\t" "movdqu %%xmm6, %[checksum]\n\t" : [checksum] "=m" (*c->u_ctr.ctr) : : "memory" ); } static unsigned int ASM_FUNC_ATTR_NOINLINE aesni_ocb_enc (gcry_cipher_hd_t c, void *outbuf_arg, const void *inbuf_arg, size_t nblocks) { RIJNDAEL_context *ctx = (void *)&c->context.c; unsigned char *outbuf = outbuf_arg; const unsigned char *inbuf = inbuf_arg; u64 n = c->u_mode.ocb.data_nblocks; const unsigned char *l; byte tmpbuf_store[3 * 16 + 15]; byte *tmpbuf; aesni_prepare_2_7_variable; asm volatile ("" : "=r" (tmpbuf) : "0" (tmpbuf_store) : "memory"); tmpbuf = tmpbuf + (-(uintptr_t)tmpbuf & 15); aesni_prepare (); aesni_prepare_2_7 (); /* Preload Offset */ asm volatile ("movdqu %[iv], %%xmm5\n\t" "movdqu %[ctr], %%xmm7\n\t" : /* No output */ : [iv] "m" (*c->u_iv.iv), [ctr] "m" (*c->u_ctr.ctr) : "memory" ); for ( ;nblocks && n % 4; nblocks-- ) { l = aes_ocb_get_l(c, ++n); /* Checksum_i = Checksum_{i-1} xor P_i */ /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */ /* C_i = Offset_i xor ENCIPHER(K, P_i xor Offset_i) */ asm volatile ("movdqu %[l], %%xmm1\n\t" "movdqu %[inbuf], %%xmm0\n\t" "pxor %%xmm1, %%xmm5\n\t" "pxor %%xmm0, %%xmm7\n\t" "pxor %%xmm5, %%xmm0\n\t" : : [l] "m" (*l), [inbuf] "m" (*inbuf) : "memory" ); do_aesni_enc (ctx); asm volatile ("pxor %%xmm5, %%xmm0\n\t" "movdqu %%xmm0, %[outbuf]\n\t" : [outbuf] "=m" (*outbuf) : : "memory" ); inbuf += BLOCKSIZE; outbuf += BLOCKSIZE; } #ifdef __x86_64__ if (nblocks >= 8) { unsigned char last_xor_first_key_store[16 + 15]; unsigned char *lxf_key; aesni_prepare_8_15_variable; asm volatile ("" : "=r" (lxf_key) : "0" (last_xor_first_key_store) : "memory"); lxf_key = lxf_key + (-(uintptr_t)lxf_key & 15); aesni_prepare_8_15(); asm volatile ("movdqu %[l0], %%xmm6\n\t" "movdqa %[last_key], %%xmm0\n\t" "pxor %[first_key], %%xmm5\n\t" "pxor %[first_key], %%xmm0\n\t" "movdqa %%xmm0, %[lxfkey]\n\t" : [lxfkey] "=m" (*lxf_key) : [l0] "m" (*c->u_mode.ocb.L[0]), [last_key] "m" (ctx->keyschenc[ctx->rounds][0][0]), [first_key] "m" (ctx->keyschenc[0][0][0]) : "memory" ); for ( ;nblocks >= 8 ; nblocks -= 8 ) { n += 4; l = aes_ocb_get_l(c, n); asm volatile ("movdqu %[l0l1], %%xmm10\n\t" "movdqu %[l1], %%xmm11\n\t" "movdqu %[l3], %%xmm15\n\t" : : [l0l1] "m" (*c->u_mode.ocb.L0L1), [l1] "m" (*c->u_mode.ocb.L[1]), [l3] "m" (*l) : "memory" ); n += 4; l = aes_ocb_get_l(c, n); /* Checksum_i = Checksum_{i-1} xor P_i */ /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */ /* P_i = Offset_i xor ENCIPHER(K, C_i xor Offset_i) */ asm volatile ("movdqu %[inbuf0], %%xmm1\n\t" "movdqu %[inbuf1], %%xmm2\n\t" "movdqu %[inbuf2], %%xmm3\n\t" : : [inbuf0] "m" (*(inbuf + 0 * BLOCKSIZE)), [inbuf1] "m" (*(inbuf + 1 * BLOCKSIZE)), [inbuf2] "m" (*(inbuf + 2 * BLOCKSIZE)) : "memory" ); asm volatile ("movdqu %[inbuf3], %%xmm4\n\t" "movdqu %[inbuf4], %%xmm8\n\t" "movdqu %[inbuf5], %%xmm9\n\t" : : [inbuf3] "m" (*(inbuf + 3 * BLOCKSIZE)), [inbuf4] "m" (*(inbuf + 4 * BLOCKSIZE)), [inbuf5] "m" (*(inbuf + 5 * BLOCKSIZE)) : "memory" ); asm volatile ("movdqa %[lxfkey], %%xmm0\n\t" "movdqa %%xmm6, %%xmm12\n\t" "pxor %%xmm5, %%xmm12\n\t" "pxor %%xmm1, %%xmm7\n\t" "pxor %%xmm12, %%xmm1\n\t" "pxor %%xmm0, %%xmm12\n\t" "movdqa %%xmm10, %%xmm13\n\t" "pxor %%xmm5, %%xmm13\n\t" "pxor %%xmm2, %%xmm7\n\t" "pxor %%xmm13, %%xmm2\n\t" "pxor %%xmm0, %%xmm13\n\t" "movdqa %%xmm11, %%xmm14\n\t" "pxor %%xmm5, %%xmm14\n\t" "pxor %%xmm3, %%xmm7\n\t" "pxor %%xmm14, %%xmm3\n\t" "pxor %%xmm0, %%xmm14\n\t" "pxor %%xmm11, %%xmm5\n\t" "pxor %%xmm15, %%xmm5\n\t" "pxor %%xmm4, %%xmm7\n\t" "pxor %%xmm5, %%xmm4\n\t" "movdqa %%xmm5, %%xmm15\n\t" "pxor %%xmm0, %%xmm15\n\t" "movdqa %%xmm5, %%xmm0\n\t" "pxor %%xmm6, %%xmm0\n\t" "pxor %%xmm8, %%xmm7\n\t" "pxor %%xmm0, %%xmm8\n\t" "pxor %[lxfkey], %%xmm0\n\t" "movdqa %%xmm0, %[tmpbuf0]\n\t" "movdqa %%xmm10, %%xmm0\n\t" "pxor %%xmm5, %%xmm0\n\t" "pxor %%xmm9, %%xmm7\n\t" "pxor %%xmm0, %%xmm9\n\t" "pxor %[lxfkey], %%xmm0\n" "movdqa %%xmm0, %[tmpbuf1]\n\t" : [tmpbuf0] "=m" (*(tmpbuf + 0 * BLOCKSIZE)), [tmpbuf1] "=m" (*(tmpbuf + 1 * BLOCKSIZE)) : [lxfkey] "m" (*lxf_key) : "memory" ); asm volatile ("movdqu %[inbuf6], %%xmm10\n\t" "movdqa %%xmm11, %%xmm0\n\t" "pxor %%xmm5, %%xmm0\n\t" "pxor %%xmm10, %%xmm7\n\t" "pxor %%xmm0, %%xmm10\n\t" "pxor %[lxfkey], %%xmm0\n\t" "movdqa %%xmm0, %[tmpbuf2]\n\t" : [tmpbuf2] "=m" (*(tmpbuf + 2 * BLOCKSIZE)) : [inbuf6] "m" (*(inbuf + 6 * BLOCKSIZE)), [lxfkey] "m" (*lxf_key) : "memory" ); asm volatile ("movdqu %[l7], %%xmm0\n\t" "pxor %%xmm11, %%xmm5\n\t" "pxor %%xmm0, %%xmm5\n\t" "movdqa 0x10(%[key]), %%xmm0\n\t" "movdqu %[inbuf7], %%xmm11\n\t" "pxor %%xmm11, %%xmm7\n\t" "pxor %%xmm5, %%xmm11\n\t" : : [l7] "m" (*l), [inbuf7] "m" (*(inbuf + 7 * BLOCKSIZE)), [key] "r" (ctx->keyschenc) : "memory" ); asm volatile ("cmpl $12, %[rounds]\n\t" "aesenc %%xmm0, %%xmm1\n\t" "aesenc %%xmm0, %%xmm2\n\t" "aesenc %%xmm0, %%xmm3\n\t" "aesenc %%xmm0, %%xmm4\n\t" "aesenc %%xmm0, %%xmm8\n\t" "aesenc %%xmm0, %%xmm9\n\t" "aesenc %%xmm0, %%xmm10\n\t" "aesenc %%xmm0, %%xmm11\n\t" "movdqa 0x20(%[key]), %%xmm0\n\t" "aesenc %%xmm0, %%xmm1\n\t" "aesenc %%xmm0, %%xmm2\n\t" "aesenc %%xmm0, %%xmm3\n\t" "aesenc %%xmm0, %%xmm4\n\t" "aesenc %%xmm0, %%xmm8\n\t" "aesenc %%xmm0, %%xmm9\n\t" "aesenc %%xmm0, %%xmm10\n\t" "aesenc %%xmm0, %%xmm11\n\t" "movdqa 0x30(%[key]), %%xmm0\n\t" "aesenc %%xmm0, %%xmm1\n\t" "aesenc %%xmm0, %%xmm2\n\t" "aesenc %%xmm0, %%xmm3\n\t" "aesenc %%xmm0, %%xmm4\n\t" "aesenc %%xmm0, %%xmm8\n\t" "aesenc %%xmm0, %%xmm9\n\t" "aesenc %%xmm0, %%xmm10\n\t" "aesenc %%xmm0, %%xmm11\n\t" "movdqa 0x40(%[key]), %%xmm0\n\t" "aesenc %%xmm0, %%xmm1\n\t" "aesenc %%xmm0, %%xmm2\n\t" "aesenc %%xmm0, %%xmm3\n\t" "aesenc %%xmm0, %%xmm4\n\t" "aesenc %%xmm0, %%xmm8\n\t" "aesenc %%xmm0, %%xmm9\n\t" "aesenc %%xmm0, %%xmm10\n\t" "aesenc %%xmm0, %%xmm11\n\t" "movdqa 0x50(%[key]), %%xmm0\n\t" "aesenc %%xmm0, %%xmm1\n\t" "aesenc %%xmm0, %%xmm2\n\t" "aesenc %%xmm0, %%xmm3\n\t" "aesenc %%xmm0, %%xmm4\n\t" "aesenc %%xmm0, %%xmm8\n\t" "aesenc %%xmm0, %%xmm9\n\t" "aesenc %%xmm0, %%xmm10\n\t" "aesenc %%xmm0, %%xmm11\n\t" "movdqa 0x60(%[key]), %%xmm0\n\t" "aesenc %%xmm0, %%xmm1\n\t" "aesenc %%xmm0, %%xmm2\n\t" "aesenc %%xmm0, %%xmm3\n\t" "aesenc %%xmm0, %%xmm4\n\t" "aesenc %%xmm0, %%xmm8\n\t" "aesenc %%xmm0, %%xmm9\n\t" "aesenc %%xmm0, %%xmm10\n\t" "aesenc %%xmm0, %%xmm11\n\t" "movdqa 0x70(%[key]), %%xmm0\n\t" "aesenc %%xmm0, %%xmm1\n\t" "aesenc %%xmm0, %%xmm2\n\t" "aesenc %%xmm0, %%xmm3\n\t" "aesenc %%xmm0, %%xmm4\n\t" "aesenc %%xmm0, %%xmm8\n\t" "aesenc %%xmm0, %%xmm9\n\t" "aesenc %%xmm0, %%xmm10\n\t" "aesenc %%xmm0, %%xmm11\n\t" "movdqa 0x80(%[key]), %%xmm0\n\t" "aesenc %%xmm0, %%xmm1\n\t" "aesenc %%xmm0, %%xmm2\n\t" "aesenc %%xmm0, %%xmm3\n\t" "aesenc %%xmm0, %%xmm4\n\t" "aesenc %%xmm0, %%xmm8\n\t" "aesenc %%xmm0, %%xmm9\n\t" "aesenc %%xmm0, %%xmm10\n\t" "aesenc %%xmm0, %%xmm11\n\t" "movdqa 0x90(%[key]), %%xmm0\n\t" "aesenc %%xmm0, %%xmm1\n\t" "aesenc %%xmm0, %%xmm2\n\t" "aesenc %%xmm0, %%xmm3\n\t" "aesenc %%xmm0, %%xmm4\n\t" "aesenc %%xmm0, %%xmm8\n\t" "aesenc %%xmm0, %%xmm9\n\t" "aesenc %%xmm0, %%xmm10\n\t" "aesenc %%xmm0, %%xmm11\n\t" "jb .Ldeclast%=\n\t" "movdqa 0xa0(%[key]), %%xmm0\n\t" "aesenc %%xmm0, %%xmm1\n\t" "aesenc %%xmm0, %%xmm2\n\t" "aesenc %%xmm0, %%xmm3\n\t" "aesenc %%xmm0, %%xmm4\n\t" "aesenc %%xmm0, %%xmm8\n\t" "aesenc %%xmm0, %%xmm9\n\t" "aesenc %%xmm0, %%xmm10\n\t" "aesenc %%xmm0, %%xmm11\n\t" "movdqa 0xb0(%[key]), %%xmm0\n\t" "aesenc %%xmm0, %%xmm1\n\t" "aesenc %%xmm0, %%xmm2\n\t" "aesenc %%xmm0, %%xmm3\n\t" "aesenc %%xmm0, %%xmm4\n\t" "aesenc %%xmm0, %%xmm8\n\t" "aesenc %%xmm0, %%xmm9\n\t" "aesenc %%xmm0, %%xmm10\n\t" "aesenc %%xmm0, %%xmm11\n\t" "je .Ldeclast%=\n\t" "movdqa 0xc0(%[key]), %%xmm0\n\t" "aesenc %%xmm0, %%xmm1\n\t" "aesenc %%xmm0, %%xmm2\n\t" "aesenc %%xmm0, %%xmm3\n\t" "aesenc %%xmm0, %%xmm4\n\t" "aesenc %%xmm0, %%xmm8\n\t" "aesenc %%xmm0, %%xmm9\n\t" "aesenc %%xmm0, %%xmm10\n\t" "aesenc %%xmm0, %%xmm11\n\t" "movdqa 0xd0(%[key]), %%xmm0\n\t" "aesenc %%xmm0, %%xmm1\n\t" "aesenc %%xmm0, %%xmm2\n\t" "aesenc %%xmm0, %%xmm3\n\t" "aesenc %%xmm0, %%xmm4\n\t" "aesenc %%xmm0, %%xmm8\n\t" "aesenc %%xmm0, %%xmm9\n\t" "aesenc %%xmm0, %%xmm10\n\t" "aesenc %%xmm0, %%xmm11\n\t" ".Ldeclast%=:\n\t" : : [key] "r" (ctx->keyschenc), [rounds] "r" (ctx->rounds) : "cc", "memory"); asm volatile ("aesenclast %%xmm12, %%xmm1\n\t" "aesenclast %%xmm13, %%xmm2\n\t" "aesenclast %%xmm14, %%xmm3\n\t" "aesenclast %%xmm15, %%xmm4\n\t" "aesenclast %[tmpbuf0],%%xmm8\n\t" "aesenclast %[tmpbuf1],%%xmm9\n\t" "aesenclast %[tmpbuf2],%%xmm10\n\t" : : [tmpbuf0] "m" (*(tmpbuf + 0 * BLOCKSIZE)), [tmpbuf1] "m" (*(tmpbuf + 1 * BLOCKSIZE)), [tmpbuf2] "m" (*(tmpbuf + 2 * BLOCKSIZE)), [lxfkey] "m" (*lxf_key) : "memory" ); asm volatile ("aesenclast %%xmm5, %%xmm11\n\t" "pxor %[lxfkey], %%xmm11\n\t" "movdqu %%xmm1, %[outbuf0]\n\t" "movdqu %%xmm2, %[outbuf1]\n\t" : [outbuf0] "=m" (*(outbuf + 0 * BLOCKSIZE)), [outbuf1] "=m" (*(outbuf + 1 * BLOCKSIZE)) : [lxfkey] "m" (*lxf_key) : "memory" ); asm volatile ("movdqu %%xmm3, %[outbuf2]\n\t" "movdqu %%xmm4, %[outbuf3]\n\t" "movdqu %%xmm8, %[outbuf4]\n\t" : [outbuf2] "=m" (*(outbuf + 2 * BLOCKSIZE)), [outbuf3] "=m" (*(outbuf + 3 * BLOCKSIZE)), [outbuf4] "=m" (*(outbuf + 4 * BLOCKSIZE)) : : "memory" ); asm volatile ("movdqu %%xmm9, %[outbuf5]\n\t" "movdqu %%xmm10, %[outbuf6]\n\t" "movdqu %%xmm11, %[outbuf7]\n\t" : [outbuf5] "=m" (*(outbuf + 5 * BLOCKSIZE)), [outbuf6] "=m" (*(outbuf + 6 * BLOCKSIZE)), [outbuf7] "=m" (*(outbuf + 7 * BLOCKSIZE)) : : "memory" ); outbuf += 8*BLOCKSIZE; inbuf += 8*BLOCKSIZE; } asm volatile ("pxor %[first_key], %%xmm5\n\t" "pxor %%xmm0, %%xmm0\n\t" "movdqu %%xmm0, %[lxfkey]\n\t" : [lxfkey] "=m" (*lxf_key) : [first_key] "m" (ctx->keyschenc[0][0][0]) : "memory" ); aesni_cleanup_8_15(); } #endif for ( ;nblocks >= 4 ; nblocks -= 4 ) { n += 4; l = aes_ocb_get_l(c, n); /* Checksum_i = Checksum_{i-1} xor P_i */ /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */ /* C_i = Offset_i xor ENCIPHER(K, P_i xor Offset_i) */ asm volatile ("movdqu %[l0], %%xmm0\n\t" "movdqu %[inbuf0], %%xmm1\n\t" "movdqu %[l0l1], %%xmm3\n\t" : : [l0] "m" (*c->u_mode.ocb.L[0]), [l0l1] "m" (*c->u_mode.ocb.L0L1), [inbuf0] "m" (*(inbuf + 0 * BLOCKSIZE)) : "memory" ); asm volatile ("movdqu %[l1], %%xmm4\n\t" "movdqu %[l3], %%xmm6\n\t" "pxor %%xmm5, %%xmm0\n\t" "pxor %%xmm1, %%xmm7\n\t" "pxor %%xmm0, %%xmm1\n\t" "movdqa %%xmm0, %[tmpbuf0]\n\t" : [tmpbuf0] "=m" (*(tmpbuf + 0 * BLOCKSIZE)) : [l1] "m" (*c->u_mode.ocb.L[1]), [l3] "m" (*l) : "memory" ); asm volatile ("movdqu %[inbuf1], %%xmm2\n\t" "pxor %%xmm5, %%xmm3\n\t" "pxor %%xmm2, %%xmm7\n\t" "pxor %%xmm3, %%xmm2\n\t" "movdqa %%xmm3, %[tmpbuf1]\n\t" : [tmpbuf1] "=m" (*(tmpbuf + 1 * BLOCKSIZE)) : [inbuf1] "m" (*(inbuf + 1 * BLOCKSIZE)) : "memory" ); asm volatile ("movdqa %%xmm4, %%xmm0\n\t" "movdqu %[inbuf2], %%xmm3\n\t" "pxor %%xmm5, %%xmm0\n\t" "pxor %%xmm3, %%xmm7\n\t" "pxor %%xmm0, %%xmm3\n\t" "movdqa %%xmm0, %[tmpbuf2]\n\t" : [tmpbuf2] "=m" (*(tmpbuf + 2 * BLOCKSIZE)) : [inbuf2] "m" (*(inbuf + 2 * BLOCKSIZE)) : "memory" ); asm volatile ("pxor %%xmm6, %%xmm5\n\t" "pxor %%xmm4, %%xmm5\n\t" "movdqu %[inbuf3], %%xmm4\n\t" "pxor %%xmm4, %%xmm7\n\t" "pxor %%xmm5, %%xmm4\n\t" : : [inbuf3] "m" (*(inbuf + 3 * BLOCKSIZE)) : "memory" ); do_aesni_enc_vec4 (ctx); asm volatile ("pxor %[tmpbuf0],%%xmm1\n\t" "movdqu %%xmm1, %[outbuf0]\n\t" "pxor %[tmpbuf1],%%xmm2\n\t" "movdqu %%xmm2, %[outbuf1]\n\t" : [outbuf0] "=m" (*(outbuf + 0 * BLOCKSIZE)), [outbuf1] "=m" (*(outbuf + 1 * BLOCKSIZE)) : [tmpbuf0] "m" (*(tmpbuf + 0 * BLOCKSIZE)), [tmpbuf1] "m" (*(tmpbuf + 1 * BLOCKSIZE)) : "memory" ); asm volatile ("pxor %[tmpbuf2],%%xmm3\n\t" "movdqu %%xmm3, %[outbuf2]\n\t" "pxor %%xmm5, %%xmm4\n\t" "movdqu %%xmm4, %[outbuf3]\n\t" : [outbuf2] "=m" (*(outbuf + 2 * BLOCKSIZE)), [outbuf3] "=m" (*(outbuf + 3 * BLOCKSIZE)) : [tmpbuf2] "m" (*(tmpbuf + 2 * BLOCKSIZE)) : "memory" ); outbuf += 4*BLOCKSIZE; inbuf += 4*BLOCKSIZE; } for ( ;nblocks; nblocks-- ) { l = aes_ocb_get_l(c, ++n); /* Checksum_i = Checksum_{i-1} xor P_i */ /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */ /* C_i = Offset_i xor ENCIPHER(K, P_i xor Offset_i) */ asm volatile ("movdqu %[l], %%xmm1\n\t" "movdqu %[inbuf], %%xmm0\n\t" "pxor %%xmm1, %%xmm5\n\t" "pxor %%xmm0, %%xmm7\n\t" "pxor %%xmm5, %%xmm0\n\t" : : [l] "m" (*l), [inbuf] "m" (*inbuf) : "memory" ); do_aesni_enc (ctx); asm volatile ("pxor %%xmm5, %%xmm0\n\t" "movdqu %%xmm0, %[outbuf]\n\t" : [outbuf] "=m" (*outbuf) : : "memory" ); inbuf += BLOCKSIZE; outbuf += BLOCKSIZE; } c->u_mode.ocb.data_nblocks = n; asm volatile ("movdqu %%xmm5, %[iv]\n\t" "movdqu %%xmm7, %[ctr]\n\t" : [iv] "=m" (*c->u_iv.iv), [ctr] "=m" (*c->u_ctr.ctr) : : "memory" ); asm volatile ("pxor %%xmm0, %%xmm0\n\t" "movdqa %%xmm0, %[tmpbuf0]\n\t" "movdqa %%xmm0, %[tmpbuf1]\n\t" "movdqa %%xmm0, %[tmpbuf2]\n\t" : [tmpbuf0] "=m" (*(tmpbuf + 0 * BLOCKSIZE)), [tmpbuf1] "=m" (*(tmpbuf + 1 * BLOCKSIZE)), [tmpbuf2] "=m" (*(tmpbuf + 2 * BLOCKSIZE)) : : "memory" ); aesni_cleanup (); aesni_cleanup_2_7 (); return 0; } static unsigned int ASM_FUNC_ATTR_NOINLINE aesni_ocb_dec (gcry_cipher_hd_t c, void *outbuf_arg, const void *inbuf_arg, size_t nblocks_arg) { RIJNDAEL_context *ctx = (void *)&c->context.c; unsigned char *outbuf = outbuf_arg; const unsigned char *inbuf = inbuf_arg; u64 n = c->u_mode.ocb.data_nblocks; const unsigned char *l; size_t nblocks = nblocks_arg; byte tmpbuf_store[3 * 16 + 15]; byte *tmpbuf; aesni_prepare_2_7_variable; asm volatile ("" : "=r" (tmpbuf) : "0" (tmpbuf_store) : "memory"); tmpbuf = tmpbuf + (-(uintptr_t)tmpbuf & 15); aesni_prepare (); aesni_prepare_2_7 (); if ( !ctx->decryption_prepared ) { do_aesni_prepare_decryption ( ctx ); ctx->decryption_prepared = 1; } /* Preload Offset */ asm volatile ("movdqu %[iv], %%xmm5\n\t" : /* No output */ : [iv] "m" (*c->u_iv.iv) : "memory" ); for ( ;nblocks && n % 4; nblocks-- ) { l = aes_ocb_get_l(c, ++n); /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */ /* P_i = Offset_i xor DECIPHER(K, C_i xor Offset_i) */ asm volatile ("movdqu %[l], %%xmm1\n\t" "movdqu %[inbuf], %%xmm0\n\t" "pxor %%xmm1, %%xmm5\n\t" "pxor %%xmm5, %%xmm0\n\t" : : [l] "m" (*l), [inbuf] "m" (*inbuf) : "memory" ); do_aesni_dec (ctx); asm volatile ("pxor %%xmm5, %%xmm0\n\t" "movdqu %%xmm0, %[outbuf]\n\t" : [outbuf] "=m" (*outbuf) : : "memory" ); inbuf += BLOCKSIZE; outbuf += BLOCKSIZE; } #ifdef __x86_64__ if (nblocks >= 8) { unsigned char last_xor_first_key_store[16 + 15]; unsigned char *lxf_key; aesni_prepare_8_15_variable; asm volatile ("" : "=r" (lxf_key) : "0" (last_xor_first_key_store) : "memory"); lxf_key = lxf_key + (-(uintptr_t)lxf_key & 15); aesni_prepare_8_15(); asm volatile ("movdqu %[l0], %%xmm6\n\t" "movdqa %[last_key], %%xmm0\n\t" "pxor %[first_key], %%xmm5\n\t" "pxor %[first_key], %%xmm0\n\t" "movdqa %%xmm0, %[lxfkey]\n\t" : [lxfkey] "=m" (*lxf_key) : [l0] "m" (*c->u_mode.ocb.L[0]), [last_key] "m" (ctx->keyschdec[ctx->rounds][0][0]), [first_key] "m" (ctx->keyschdec[0][0][0]) : "memory" ); for ( ;nblocks >= 8 ; nblocks -= 8 ) { n += 4; l = aes_ocb_get_l(c, n); asm volatile ("movdqu %[l0l1], %%xmm10\n\t" "movdqu %[l1], %%xmm11\n\t" "movdqu %[l3], %%xmm15\n\t" : : [l0l1] "m" (*c->u_mode.ocb.L0L1), [l1] "m" (*c->u_mode.ocb.L[1]), [l3] "m" (*l) : "memory" ); n += 4; l = aes_ocb_get_l(c, n); /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */ /* P_i = Offset_i xor ENCIPHER(K, C_i xor Offset_i) */ asm volatile ("movdqu %[inbuf0], %%xmm1\n\t" "movdqu %[inbuf1], %%xmm2\n\t" "movdqu %[inbuf2], %%xmm3\n\t" : : [inbuf0] "m" (*(inbuf + 0 * BLOCKSIZE)), [inbuf1] "m" (*(inbuf + 1 * BLOCKSIZE)), [inbuf2] "m" (*(inbuf + 2 * BLOCKSIZE)) : "memory" ); asm volatile ("movdqu %[inbuf3], %%xmm4\n\t" "movdqu %[inbuf4], %%xmm8\n\t" "movdqu %[inbuf5], %%xmm9\n\t" : : [inbuf3] "m" (*(inbuf + 3 * BLOCKSIZE)), [inbuf4] "m" (*(inbuf + 4 * BLOCKSIZE)), [inbuf5] "m" (*(inbuf + 5 * BLOCKSIZE)) : "memory" ); asm volatile ("movdqa %[lxfkey], %%xmm0\n\t" "movdqa %%xmm6, %%xmm12\n\t" "pxor %%xmm5, %%xmm12\n\t" "pxor %%xmm12, %%xmm1\n\t" "pxor %%xmm0, %%xmm12\n\t" "movdqa %%xmm10, %%xmm13\n\t" "pxor %%xmm5, %%xmm13\n\t" "pxor %%xmm13, %%xmm2\n\t" "pxor %%xmm0, %%xmm13\n\t" "movdqa %%xmm11, %%xmm14\n\t" "pxor %%xmm5, %%xmm14\n\t" "pxor %%xmm14, %%xmm3\n\t" "pxor %%xmm0, %%xmm14\n\t" "pxor %%xmm11, %%xmm5\n\t" "pxor %%xmm15, %%xmm5\n\t" "pxor %%xmm5, %%xmm4\n\t" "movdqa %%xmm5, %%xmm15\n\t" "pxor %%xmm0, %%xmm15\n\t" "movdqa %%xmm5, %%xmm0\n\t" "pxor %%xmm6, %%xmm0\n\t" "pxor %%xmm0, %%xmm8\n\t" "pxor %[lxfkey], %%xmm0\n\t" "movdqa %%xmm0, %[tmpbuf0]\n\t" "movdqa %%xmm10, %%xmm0\n\t" "pxor %%xmm5, %%xmm0\n\t" "pxor %%xmm0, %%xmm9\n\t" "pxor %[lxfkey], %%xmm0\n" "movdqa %%xmm0, %[tmpbuf1]\n\t" : [tmpbuf0] "=m" (*(tmpbuf + 0 * BLOCKSIZE)), [tmpbuf1] "=m" (*(tmpbuf + 1 * BLOCKSIZE)) : [lxfkey] "m" (*lxf_key) : "memory" ); asm volatile ("movdqu %[inbuf6], %%xmm10\n\t" "movdqa %%xmm11, %%xmm0\n\t" "pxor %%xmm5, %%xmm0\n\t" "pxor %%xmm0, %%xmm10\n\t" "pxor %[lxfkey], %%xmm0\n\t" "movdqa %%xmm0, %[tmpbuf2]\n\t" : [tmpbuf2] "=m" (*(tmpbuf + 2 * BLOCKSIZE)) : [inbuf6] "m" (*(inbuf + 6 * BLOCKSIZE)), [lxfkey] "m" (*lxf_key) : "memory" ); asm volatile ("movdqu %[l7], %%xmm0\n\t" "pxor %%xmm11, %%xmm5\n\t" "pxor %%xmm0, %%xmm5\n\t" "movdqa 0x10(%[key]), %%xmm0\n\t" "movdqu %[inbuf7], %%xmm11\n\t" "pxor %%xmm5, %%xmm11\n\t" : : [l7] "m" (*l), [inbuf7] "m" (*(inbuf + 7 * BLOCKSIZE)), [key] "r" (ctx->keyschdec) : "memory" ); asm volatile ("cmpl $12, %[rounds]\n\t" "aesdec %%xmm0, %%xmm1\n\t" "aesdec %%xmm0, %%xmm2\n\t" "aesdec %%xmm0, %%xmm3\n\t" "aesdec %%xmm0, %%xmm4\n\t" "aesdec %%xmm0, %%xmm8\n\t" "aesdec %%xmm0, %%xmm9\n\t" "aesdec %%xmm0, %%xmm10\n\t" "aesdec %%xmm0, %%xmm11\n\t" "movdqa 0x20(%[key]), %%xmm0\n\t" "aesdec %%xmm0, %%xmm1\n\t" "aesdec %%xmm0, %%xmm2\n\t" "aesdec %%xmm0, %%xmm3\n\t" "aesdec %%xmm0, %%xmm4\n\t" "aesdec %%xmm0, %%xmm8\n\t" "aesdec %%xmm0, %%xmm9\n\t" "aesdec %%xmm0, %%xmm10\n\t" "aesdec %%xmm0, %%xmm11\n\t" "movdqa 0x30(%[key]), %%xmm0\n\t" "aesdec %%xmm0, %%xmm1\n\t" "aesdec %%xmm0, %%xmm2\n\t" "aesdec %%xmm0, %%xmm3\n\t" "aesdec %%xmm0, %%xmm4\n\t" "aesdec %%xmm0, %%xmm8\n\t" "aesdec %%xmm0, %%xmm9\n\t" "aesdec %%xmm0, %%xmm10\n\t" "aesdec %%xmm0, %%xmm11\n\t" "movdqa 0x40(%[key]), %%xmm0\n\t" "aesdec %%xmm0, %%xmm1\n\t" "aesdec %%xmm0, %%xmm2\n\t" "aesdec %%xmm0, %%xmm3\n\t" "aesdec %%xmm0, %%xmm4\n\t" "aesdec %%xmm0, %%xmm8\n\t" "aesdec %%xmm0, %%xmm9\n\t" "aesdec %%xmm0, %%xmm10\n\t" "aesdec %%xmm0, %%xmm11\n\t" "movdqa 0x50(%[key]), %%xmm0\n\t" "aesdec %%xmm0, %%xmm1\n\t" "aesdec %%xmm0, %%xmm2\n\t" "aesdec %%xmm0, %%xmm3\n\t" "aesdec %%xmm0, %%xmm4\n\t" "aesdec %%xmm0, %%xmm8\n\t" "aesdec %%xmm0, %%xmm9\n\t" "aesdec %%xmm0, %%xmm10\n\t" "aesdec %%xmm0, %%xmm11\n\t" "movdqa 0x60(%[key]), %%xmm0\n\t" "aesdec %%xmm0, %%xmm1\n\t" "aesdec %%xmm0, %%xmm2\n\t" "aesdec %%xmm0, %%xmm3\n\t" "aesdec %%xmm0, %%xmm4\n\t" "aesdec %%xmm0, %%xmm8\n\t" "aesdec %%xmm0, %%xmm9\n\t" "aesdec %%xmm0, %%xmm10\n\t" "aesdec %%xmm0, %%xmm11\n\t" "movdqa 0x70(%[key]), %%xmm0\n\t" "aesdec %%xmm0, %%xmm1\n\t" "aesdec %%xmm0, %%xmm2\n\t" "aesdec %%xmm0, %%xmm3\n\t" "aesdec %%xmm0, %%xmm4\n\t" "aesdec %%xmm0, %%xmm8\n\t" "aesdec %%xmm0, %%xmm9\n\t" "aesdec %%xmm0, %%xmm10\n\t" "aesdec %%xmm0, %%xmm11\n\t" "movdqa 0x80(%[key]), %%xmm0\n\t" "aesdec %%xmm0, %%xmm1\n\t" "aesdec %%xmm0, %%xmm2\n\t" "aesdec %%xmm0, %%xmm3\n\t" "aesdec %%xmm0, %%xmm4\n\t" "aesdec %%xmm0, %%xmm8\n\t" "aesdec %%xmm0, %%xmm9\n\t" "aesdec %%xmm0, %%xmm10\n\t" "aesdec %%xmm0, %%xmm11\n\t" "movdqa 0x90(%[key]), %%xmm0\n\t" "aesdec %%xmm0, %%xmm1\n\t" "aesdec %%xmm0, %%xmm2\n\t" "aesdec %%xmm0, %%xmm3\n\t" "aesdec %%xmm0, %%xmm4\n\t" "aesdec %%xmm0, %%xmm8\n\t" "aesdec %%xmm0, %%xmm9\n\t" "aesdec %%xmm0, %%xmm10\n\t" "aesdec %%xmm0, %%xmm11\n\t" "jb .Ldeclast%=\n\t" "movdqa 0xa0(%[key]), %%xmm0\n\t" "aesdec %%xmm0, %%xmm1\n\t" "aesdec %%xmm0, %%xmm2\n\t" "aesdec %%xmm0, %%xmm3\n\t" "aesdec %%xmm0, %%xmm4\n\t" "aesdec %%xmm0, %%xmm8\n\t" "aesdec %%xmm0, %%xmm9\n\t" "aesdec %%xmm0, %%xmm10\n\t" "aesdec %%xmm0, %%xmm11\n\t" "movdqa 0xb0(%[key]), %%xmm0\n\t" "aesdec %%xmm0, %%xmm1\n\t" "aesdec %%xmm0, %%xmm2\n\t" "aesdec %%xmm0, %%xmm3\n\t" "aesdec %%xmm0, %%xmm4\n\t" "aesdec %%xmm0, %%xmm8\n\t" "aesdec %%xmm0, %%xmm9\n\t" "aesdec %%xmm0, %%xmm10\n\t" "aesdec %%xmm0, %%xmm11\n\t" "je .Ldeclast%=\n\t" "movdqa 0xc0(%[key]), %%xmm0\n\t" "aesdec %%xmm0, %%xmm1\n\t" "aesdec %%xmm0, %%xmm2\n\t" "aesdec %%xmm0, %%xmm3\n\t" "aesdec %%xmm0, %%xmm4\n\t" "aesdec %%xmm0, %%xmm8\n\t" "aesdec %%xmm0, %%xmm9\n\t" "aesdec %%xmm0, %%xmm10\n\t" "aesdec %%xmm0, %%xmm11\n\t" "movdqa 0xd0(%[key]), %%xmm0\n\t" "aesdec %%xmm0, %%xmm1\n\t" "aesdec %%xmm0, %%xmm2\n\t" "aesdec %%xmm0, %%xmm3\n\t" "aesdec %%xmm0, %%xmm4\n\t" "aesdec %%xmm0, %%xmm8\n\t" "aesdec %%xmm0, %%xmm9\n\t" "aesdec %%xmm0, %%xmm10\n\t" "aesdec %%xmm0, %%xmm11\n\t" ".Ldeclast%=:\n\t" : : [key] "r" (ctx->keyschdec), [rounds] "r" (ctx->rounds) : "cc", "memory"); asm volatile ("aesdeclast %%xmm12, %%xmm1\n\t" "aesdeclast %%xmm13, %%xmm2\n\t" "aesdeclast %%xmm14, %%xmm3\n\t" "aesdeclast %%xmm15, %%xmm4\n\t" "aesdeclast %[tmpbuf0],%%xmm8\n\t" "aesdeclast %[tmpbuf1],%%xmm9\n\t" "aesdeclast %[tmpbuf2],%%xmm10\n\t" : : [tmpbuf0] "m" (*(tmpbuf + 0 * BLOCKSIZE)), [tmpbuf1] "m" (*(tmpbuf + 1 * BLOCKSIZE)), [tmpbuf2] "m" (*(tmpbuf + 2 * BLOCKSIZE)) : "memory" ); asm volatile ("aesdeclast %%xmm5, %%xmm11\n\t" "pxor %[lxfkey], %%xmm11\n\t" "movdqu %%xmm1, %[outbuf0]\n\t" "movdqu %%xmm2, %[outbuf1]\n\t" : [outbuf0] "=m" (*(outbuf + 0 * BLOCKSIZE)), [outbuf1] "=m" (*(outbuf + 1 * BLOCKSIZE)) : [lxfkey] "m" (*lxf_key) : "memory" ); asm volatile ("movdqu %%xmm3, %[outbuf2]\n\t" "movdqu %%xmm4, %[outbuf3]\n\t" "movdqu %%xmm8, %[outbuf4]\n\t" : [outbuf2] "=m" (*(outbuf + 2 * BLOCKSIZE)), [outbuf3] "=m" (*(outbuf + 3 * BLOCKSIZE)), [outbuf4] "=m" (*(outbuf + 4 * BLOCKSIZE)) : : "memory" ); asm volatile ("movdqu %%xmm9, %[outbuf5]\n\t" "movdqu %%xmm10, %[outbuf6]\n\t" "movdqu %%xmm11, %[outbuf7]\n\t" : [outbuf5] "=m" (*(outbuf + 5 * BLOCKSIZE)), [outbuf6] "=m" (*(outbuf + 6 * BLOCKSIZE)), [outbuf7] "=m" (*(outbuf + 7 * BLOCKSIZE)) : : "memory" ); outbuf += 8*BLOCKSIZE; inbuf += 8*BLOCKSIZE; } asm volatile ("pxor %[first_key], %%xmm5\n\t" "pxor %%xmm0, %%xmm0\n\t" "movdqu %%xmm0, %[lxfkey]\n\t" : [lxfkey] "=m" (*lxf_key) : [first_key] "m" (ctx->keyschdec[0][0][0]) : "memory" ); aesni_cleanup_8_15(); } #endif for ( ;nblocks >= 4 ; nblocks -= 4 ) { n += 4; l = aes_ocb_get_l(c, n); /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */ /* C_i = Offset_i xor DECIPHER(K, P_i xor Offset_i) */ asm volatile ("movdqu %[l0], %%xmm0\n\t" "movdqu %[inbuf0], %%xmm1\n\t" "movdqu %[l0l1], %%xmm3\n\t" : : [l0] "m" (*c->u_mode.ocb.L[0]), [l0l1] "m" (*c->u_mode.ocb.L0L1), [inbuf0] "m" (*(inbuf + 0 * BLOCKSIZE)) : "memory" ); asm volatile ("movdqu %[l1], %%xmm4\n\t" "movdqu %[l3], %%xmm6\n\t" "pxor %%xmm5, %%xmm0\n\t" "pxor %%xmm0, %%xmm1\n\t" "movdqa %%xmm0, %[tmpbuf0]\n\t" : [tmpbuf0] "=m" (*(tmpbuf + 0 * BLOCKSIZE)) : [l1] "m" (*c->u_mode.ocb.L[1]), [l3] "m" (*l) : "memory" ); asm volatile ("movdqu %[inbuf1], %%xmm2\n\t" "pxor %%xmm5, %%xmm3\n\t" "pxor %%xmm3, %%xmm2\n\t" "movdqa %%xmm3, %[tmpbuf1]\n\t" : [tmpbuf1] "=m" (*(tmpbuf + 1 * BLOCKSIZE)) : [inbuf1] "m" (*(inbuf + 1 * BLOCKSIZE)) : "memory" ); asm volatile ("movdqa %%xmm4, %%xmm0\n\t" "movdqu %[inbuf2], %%xmm3\n\t" "pxor %%xmm5, %%xmm0\n\t" "pxor %%xmm0, %%xmm3\n\t" "movdqa %%xmm0, %[tmpbuf2]\n\t" : [tmpbuf2] "=m" (*(tmpbuf + 2 * BLOCKSIZE)) : [inbuf2] "m" (*(inbuf + 2 * BLOCKSIZE)) : "memory" ); asm volatile ("pxor %%xmm6, %%xmm5\n\t" "pxor %%xmm4, %%xmm5\n\t" "movdqu %[inbuf3], %%xmm4\n\t" "pxor %%xmm5, %%xmm4\n\t" : : [inbuf3] "m" (*(inbuf + 3 * BLOCKSIZE)) : "memory" ); do_aesni_dec_vec4 (ctx); asm volatile ("pxor %[tmpbuf0],%%xmm1\n\t" "movdqu %%xmm1, %[outbuf0]\n\t" "pxor %[tmpbuf1],%%xmm2\n\t" "movdqu %%xmm2, %[outbuf1]\n\t" : [outbuf0] "=m" (*(outbuf + 0 * BLOCKSIZE)), [outbuf1] "=m" (*(outbuf + 1 * BLOCKSIZE)) : [tmpbuf0] "m" (*(tmpbuf + 0 * BLOCKSIZE)), [tmpbuf1] "m" (*(tmpbuf + 1 * BLOCKSIZE)) : "memory" ); asm volatile ("pxor %[tmpbuf2],%%xmm3\n\t" "movdqu %%xmm3, %[outbuf2]\n\t" "pxor %%xmm5, %%xmm4\n\t" "movdqu %%xmm4, %[outbuf3]\n\t" : [outbuf2] "=m" (*(outbuf + 2 * BLOCKSIZE)), [outbuf3] "=m" (*(outbuf + 3 * BLOCKSIZE)) : [tmpbuf2] "m" (*(tmpbuf + 2 * BLOCKSIZE)) : "memory" ); outbuf += 4*BLOCKSIZE; inbuf += 4*BLOCKSIZE; } for ( ;nblocks; nblocks-- ) { l = aes_ocb_get_l(c, ++n); /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */ /* P_i = Offset_i xor DECIPHER(K, C_i xor Offset_i) */ /* Checksum_i = Checksum_{i-1} xor P_i */ asm volatile ("movdqu %[l], %%xmm1\n\t" "movdqu %[inbuf], %%xmm0\n\t" "pxor %%xmm1, %%xmm5\n\t" "pxor %%xmm5, %%xmm0\n\t" : : [l] "m" (*l), [inbuf] "m" (*inbuf) : "memory" ); do_aesni_dec (ctx); asm volatile ("pxor %%xmm5, %%xmm0\n\t" "movdqu %%xmm0, %[outbuf]\n\t" : [outbuf] "=m" (*outbuf) : : "memory" ); inbuf += BLOCKSIZE; outbuf += BLOCKSIZE; } c->u_mode.ocb.data_nblocks = n; asm volatile ("movdqu %%xmm5, %[iv]\n\t" : [iv] "=m" (*c->u_iv.iv) : : "memory" ); asm volatile ("pxor %%xmm0, %%xmm0\n\t" "movdqa %%xmm0, %[tmpbuf0]\n\t" "movdqa %%xmm0, %[tmpbuf1]\n\t" "movdqa %%xmm0, %[tmpbuf2]\n\t" : [tmpbuf0] "=m" (*(tmpbuf + 0 * BLOCKSIZE)), [tmpbuf1] "=m" (*(tmpbuf + 1 * BLOCKSIZE)), [tmpbuf2] "=m" (*(tmpbuf + 2 * BLOCKSIZE)) : : "memory" ); aesni_ocb_checksum (c, outbuf_arg, nblocks_arg); aesni_cleanup (); aesni_cleanup_2_7 (); return 0; } size_t ASM_FUNC_ATTR _gcry_aes_aesni_ocb_crypt(gcry_cipher_hd_t c, void *outbuf_arg, const void *inbuf_arg, size_t nblocks, int encrypt) { if (encrypt) return aesni_ocb_enc(c, outbuf_arg, inbuf_arg, nblocks); else return aesni_ocb_dec(c, outbuf_arg, inbuf_arg, nblocks); } size_t ASM_FUNC_ATTR _gcry_aes_aesni_ocb_auth (gcry_cipher_hd_t c, const void *abuf_arg, size_t nblocks) { RIJNDAEL_context *ctx = (void *)&c->context.c; const unsigned char *abuf = abuf_arg; u64 n = c->u_mode.ocb.aad_nblocks; const unsigned char *l; aesni_prepare_2_7_variable; aesni_prepare (); aesni_prepare_2_7 (); /* Preload Offset and Sum */ asm volatile ("movdqu %[iv], %%xmm5\n\t" "movdqu %[ctr], %%xmm6\n\t" : /* No output */ : [iv] "m" (*c->u_mode.ocb.aad_offset), [ctr] "m" (*c->u_mode.ocb.aad_sum) : "memory" ); for ( ;nblocks && n % 4; nblocks-- ) { l = aes_ocb_get_l(c, ++n); /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */ /* Sum_i = Sum_{i-1} xor ENCIPHER(K, A_i xor Offset_i) */ asm volatile ("movdqu %[l], %%xmm1\n\t" "movdqu %[abuf], %%xmm0\n\t" "pxor %%xmm1, %%xmm5\n\t" "pxor %%xmm5, %%xmm0\n\t" : : [l] "m" (*l), [abuf] "m" (*abuf) : "memory" ); do_aesni_enc (ctx); asm volatile ("pxor %%xmm0, %%xmm6\n\t" : : : "memory" ); abuf += BLOCKSIZE; } #ifdef __x86_64__ if (nblocks >= 8) { aesni_prepare_8_15_variable; aesni_prepare_8_15(); asm volatile ("movdqu %[l0], %%xmm7\n\t" "movdqu %[l0l1], %%xmm12\n\t" "movdqu %[l1], %%xmm13\n\t" : : [l0] "m" (*c->u_mode.ocb.L[0]), [l0l1] "m" (*c->u_mode.ocb.L0L1), [l1] "m" (*c->u_mode.ocb.L[1]) : "memory" ); for ( ;nblocks >= 8 ; nblocks -= 8 ) { n += 4; l = aes_ocb_get_l(c, n); asm volatile ("movdqu %[l3], %%xmm0\n\t" "pxor %%xmm13, %%xmm0\n\t" : : [l3] "m" (*l) : "memory" ); n += 4; l = aes_ocb_get_l(c, n); asm volatile ("movdqu %[l7], %%xmm14\n\t" "pxor %%xmm13, %%xmm14\n\t" : : [l7] "m" (*l) : "memory" ); /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */ /* Sum_i = Sum_{i-1} xor ENCIPHER(K, A_i xor Offset_i) */ asm volatile ("movdqu %[abuf0], %%xmm1\n\t" "movdqu %[abuf1], %%xmm2\n\t" "movdqu %[abuf2], %%xmm3\n\t" "movdqu %[abuf3], %%xmm4\n\t" : : [abuf0] "m" (*(abuf + 0 * BLOCKSIZE)), [abuf1] "m" (*(abuf + 1 * BLOCKSIZE)), [abuf2] "m" (*(abuf + 2 * BLOCKSIZE)), [abuf3] "m" (*(abuf + 3 * BLOCKSIZE)) : "memory" ); asm volatile ("movdqu %[abuf4], %%xmm8\n\t" "movdqu %[abuf5], %%xmm9\n\t" "movdqu %[abuf6], %%xmm10\n\t" "movdqu %[abuf7], %%xmm11\n\t" : : [abuf4] "m" (*(abuf + 4 * BLOCKSIZE)), [abuf5] "m" (*(abuf + 5 * BLOCKSIZE)), [abuf6] "m" (*(abuf + 6 * BLOCKSIZE)), [abuf7] "m" (*(abuf + 7 * BLOCKSIZE)) : "memory" ); asm volatile ("pxor %%xmm7, %%xmm1\n\t" "pxor %%xmm5, %%xmm1\n\t" "pxor %%xmm12, %%xmm2\n\t" "pxor %%xmm5, %%xmm2\n\t" "pxor %%xmm13, %%xmm3\n\t" "pxor %%xmm5, %%xmm3\n\t" "pxor %%xmm0, %%xmm5\n\t" "movdqa (%[key]), %%xmm0\n\t" "pxor %%xmm5, %%xmm4\n\t" "pxor %%xmm0, %%xmm1\n\t" /* xmm1 ^= key[0] */ "pxor %%xmm0, %%xmm2\n\t" /* xmm2 ^= key[0] */ "pxor %%xmm0, %%xmm3\n\t" /* xmm3 ^= key[0] */ "pxor %%xmm0, %%xmm4\n\t" /* xmm4 ^= key[0] */ "pxor %%xmm7, %%xmm8\n\t" "pxor %%xmm5, %%xmm8\n\t" "pxor %%xmm12, %%xmm9\n\t" "pxor %%xmm5, %%xmm9\n\t" "pxor %%xmm13, %%xmm10\n\t" "pxor %%xmm5, %%xmm10\n\t" "pxor %%xmm14, %%xmm5\n\t" "pxor %%xmm5, %%xmm11\n\t" "pxor %%xmm0, %%xmm8\n\t" /* xmm8 ^= key[0] */ "pxor %%xmm0, %%xmm9\n\t" /* xmm9 ^= key[0] */ "pxor %%xmm0, %%xmm10\n\t" /* xmm10 ^= key[0] */ "pxor %%xmm0, %%xmm11\n\t" /* xmm11 ^= key[0] */ : : [key] "r" (ctx->keyschenc) : "memory" ); do_aesni_enc_vec8 (ctx); asm volatile ( "aesenclast %%xmm0, %%xmm1\n\t" "aesenclast %%xmm0, %%xmm2\n\t" "aesenclast %%xmm0, %%xmm3\n\t" "aesenclast %%xmm0, %%xmm4\n\t" "aesenclast %%xmm0, %%xmm8\n\t" "aesenclast %%xmm0, %%xmm9\n\t" "aesenclast %%xmm0, %%xmm10\n\t" "aesenclast %%xmm0, %%xmm11\n\t" "pxor %%xmm2, %%xmm1\n\t" "pxor %%xmm3, %%xmm1\n\t" "pxor %%xmm4, %%xmm1\n\t" "pxor %%xmm8, %%xmm1\n\t" "pxor %%xmm9, %%xmm6\n\t" "pxor %%xmm10, %%xmm6\n\t" "pxor %%xmm11, %%xmm6\n\t" "pxor %%xmm1, %%xmm6\n\t" : : : "memory" ); abuf += 8*BLOCKSIZE; } aesni_cleanup_8_15(); } #endif for ( ;nblocks >= 4 ; nblocks -= 4 ) { n += 4; l = aes_ocb_get_l(c, n); /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */ /* Sum_i = Sum_{i-1} xor ENCIPHER(K, A_i xor Offset_i) */ asm volatile ("movdqu %[l0], %%xmm0\n\t" "movdqu %[abuf0], %%xmm1\n\t" "movdqu %[l0l1], %%xmm3\n\t" : : [l0] "m" (*c->u_mode.ocb.L[0]), [l0l1] "m" (*c->u_mode.ocb.L0L1), [abuf0] "m" (*(abuf + 0 * BLOCKSIZE)) : "memory" ); asm volatile ("movdqu %[l1], %%xmm4\n\t" "movdqu %[l3], %%xmm7\n\t" "pxor %%xmm5, %%xmm0\n\t" "pxor %%xmm0, %%xmm1\n\t" : : [l1] "m" (*c->u_mode.ocb.L[1]), [l3] "m" (*l) : "memory" ); asm volatile ("movdqu %[abuf1], %%xmm2\n\t" "pxor %%xmm5, %%xmm3\n\t" "pxor %%xmm3, %%xmm2\n\t" : : [abuf1] "m" (*(abuf + 1 * BLOCKSIZE)) : "memory" ); asm volatile ("movdqa %%xmm4, %%xmm0\n\t" "movdqu %[abuf2], %%xmm3\n\t" "pxor %%xmm5, %%xmm0\n\t" "pxor %%xmm0, %%xmm3\n\t" : : [abuf2] "m" (*(abuf + 2 * BLOCKSIZE)) : "memory" ); asm volatile ("pxor %%xmm7, %%xmm5\n\t" "pxor %%xmm4, %%xmm5\n\t" "movdqu %[abuf3], %%xmm4\n\t" "pxor %%xmm5, %%xmm4\n\t" : : [abuf3] "m" (*(abuf + 3 * BLOCKSIZE)) : "memory" ); do_aesni_enc_vec4 (ctx); asm volatile ("pxor %%xmm1, %%xmm6\n\t" "pxor %%xmm2, %%xmm6\n\t" "pxor %%xmm3, %%xmm6\n\t" "pxor %%xmm4, %%xmm6\n\t" : : : "memory" ); abuf += 4*BLOCKSIZE; } for ( ;nblocks; nblocks-- ) { l = aes_ocb_get_l(c, ++n); /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */ /* Sum_i = Sum_{i-1} xor ENCIPHER(K, A_i xor Offset_i) */ asm volatile ("movdqu %[l], %%xmm1\n\t" "movdqu %[abuf], %%xmm0\n\t" "pxor %%xmm1, %%xmm5\n\t" "pxor %%xmm5, %%xmm0\n\t" : : [l] "m" (*l), [abuf] "m" (*abuf) : "memory" ); do_aesni_enc (ctx); asm volatile ("pxor %%xmm0, %%xmm6\n\t" : : : "memory" ); abuf += BLOCKSIZE; } c->u_mode.ocb.aad_nblocks = n; asm volatile ("movdqu %%xmm5, %[iv]\n\t" "movdqu %%xmm6, %[ctr]\n\t" : [iv] "=m" (*c->u_mode.ocb.aad_offset), [ctr] "=m" (*c->u_mode.ocb.aad_sum) : : "memory" ); aesni_cleanup (); aesni_cleanup_2_7 (); return 0; } static const u64 xts_gfmul_const[2] __attribute__ ((aligned (16))) = { 0x87, 0x01 }; static void ASM_FUNC_ATTR _gcry_aes_aesni_xts_enc (RIJNDAEL_context *ctx, unsigned char *tweak, unsigned char *outbuf, const unsigned char *inbuf, size_t nblocks) { aesni_prepare_2_7_variable; aesni_prepare (); aesni_prepare_2_7 (); /* Preload Tweak */ asm volatile ("movdqu %[tweak], %%xmm5\n\t" "movdqa %[gfmul], %%xmm6\n\t" : : [tweak] "m" (*tweak), [gfmul] "m" (*xts_gfmul_const) : "memory" ); #ifdef __x86_64__ if (nblocks >= 8) { aesni_prepare_8_15_variable; aesni_prepare_8_15(); for ( ;nblocks >= 8 ; nblocks -= 8 ) { asm volatile ("pshufd $0x13, %%xmm5, %%xmm11\n\t" "movdqu %[inbuf0], %%xmm1\n\t" "pxor %%xmm5, %%xmm1\n\t" "movdqa %%xmm5, %%xmm7\n\t" "movdqa %%xmm11, %%xmm0\n\t" "paddd %%xmm11, %%xmm11\n\t" "psrad $31, %%xmm0\n\t" "paddq %%xmm5, %%xmm5\n\t" "pand %%xmm6, %%xmm0\n\t" "pxor %%xmm0, %%xmm5\n\t" : : [inbuf0] "m" (*(inbuf + 0 * 16)) : "memory" ); asm volatile ("movdqu %[inbuf1], %%xmm2\n\t" "pxor %%xmm5, %%xmm2\n\t" "movdqa %%xmm5, %%xmm12\n\t" "movdqa %%xmm11, %%xmm0\n\t" "paddd %%xmm11, %%xmm11\n\t" "psrad $31, %%xmm0\n\t" "paddq %%xmm5, %%xmm5\n\t" "pand %%xmm6, %%xmm0\n\t" "pxor %%xmm0, %%xmm5\n\t" : : [inbuf1] "m" (*(inbuf + 1 * 16)) : "memory" ); asm volatile ("movdqu %[inbuf2], %%xmm3\n\t" "pxor %%xmm5, %%xmm3\n\t" "movdqa %%xmm5, %%xmm13\n\t" "movdqa %%xmm11, %%xmm0\n\t" "paddd %%xmm11, %%xmm11\n\t" "psrad $31, %%xmm0\n\t" "paddq %%xmm5, %%xmm5\n\t" "pand %%xmm6, %%xmm0\n\t" "pxor %%xmm0, %%xmm5\n\t" : : [inbuf2] "m" (*(inbuf + 2 * 16)) : "memory" ); asm volatile ("movdqu %[inbuf3], %%xmm4\n\t" "pxor %%xmm5, %%xmm4\n\t" "movdqa %%xmm5, %%xmm14\n\t" "movdqa %%xmm11, %%xmm0\n\t" "paddd %%xmm11, %%xmm11\n\t" "psrad $31, %%xmm0\n\t" "paddq %%xmm5, %%xmm5\n\t" "pand %%xmm6, %%xmm0\n\t" "pxor %%xmm0, %%xmm5\n\t" : : [inbuf3] "m" (*(inbuf + 3 * 16)) : "memory" ); asm volatile ("movdqu %[inbuf4], %%xmm8\n\t" "pxor %%xmm5, %%xmm8\n\t" "movdqa %%xmm5, %%xmm15\n\t" "movdqa %%xmm11, %%xmm0\n\t" "paddd %%xmm11, %%xmm11\n\t" "psrad $31, %%xmm0\n\t" "paddq %%xmm5, %%xmm5\n\t" "pand %%xmm6, %%xmm0\n\t" "pxor %%xmm0, %%xmm5\n\t" : : [inbuf4] "m" (*(inbuf + 4 * 16)) : "memory" ); asm volatile ("movdqu %[inbuf5], %%xmm9\n\t" "pxor %%xmm5, %%xmm9\n\t" "movdqu %%xmm5, %[outbuf5]\n\t" "movdqa %%xmm11, %%xmm0\n\t" "paddd %%xmm11, %%xmm11\n\t" "psrad $31, %%xmm0\n\t" "paddq %%xmm5, %%xmm5\n\t" "pand %%xmm6, %%xmm0\n\t" "pxor %%xmm0, %%xmm5\n\t" : [outbuf5] "=m" (*(outbuf + 5 * 16)) : [inbuf5] "m" (*(inbuf + 5 * 16)) : "memory" ); asm volatile ("movdqu %[inbuf6], %%xmm10\n\t" "pxor %%xmm5, %%xmm10\n\t" "movdqu %%xmm5, %[outbuf6]\n\t" "movdqa %%xmm11, %%xmm0\n\t" "paddd %%xmm11, %%xmm11\n\t" "psrad $31, %%xmm0\n\t" "paddq %%xmm5, %%xmm5\n\t" "pand %%xmm6, %%xmm0\n\t" "pxor %%xmm0, %%xmm5\n\t" : [outbuf6] "=m" (*(outbuf + 6 * 16)) : [inbuf6] "m" (*(inbuf + 6 * 16)) : "memory" ); asm volatile ("movdqa %%xmm11, %%xmm0\n\t" "movdqu %[inbuf7], %%xmm11\n\t" "pxor %%xmm5, %%xmm11\n\t" "movdqu %%xmm5, %[outbuf7]\n\t" "psrad $31, %%xmm0\n\t" "paddq %%xmm5, %%xmm5\n\t" "pand %%xmm6, %%xmm0\n\t" "pxor %%xmm0, %%xmm5\n\t" : [outbuf7] "=m" (*(outbuf + 7 * 16)) : [inbuf7] "m" (*(inbuf + 7 * 16)) : "memory" ); asm volatile ("cmpl $12, %[rounds]\n\t" "movdqa (%[key]), %%xmm0\n\t" "pxor %%xmm0, %%xmm1\n\t" "pxor %%xmm0, %%xmm2\n\t" "pxor %%xmm0, %%xmm3\n\t" "pxor %%xmm0, %%xmm4\n\t" "pxor %%xmm0, %%xmm8\n\t" "pxor %%xmm0, %%xmm9\n\t" "pxor %%xmm0, %%xmm10\n\t" "pxor %%xmm0, %%xmm11\n\t" "movdqa 0x10(%[key]), %%xmm0\n\t" "aesenc %%xmm0, %%xmm1\n\t" "aesenc %%xmm0, %%xmm2\n\t" "aesenc %%xmm0, %%xmm3\n\t" "aesenc %%xmm0, %%xmm4\n\t" "aesenc %%xmm0, %%xmm8\n\t" "aesenc %%xmm0, %%xmm9\n\t" "aesenc %%xmm0, %%xmm10\n\t" "aesenc %%xmm0, %%xmm11\n\t" "movdqa 0x20(%[key]), %%xmm0\n\t" "aesenc %%xmm0, %%xmm1\n\t" "aesenc %%xmm0, %%xmm2\n\t" "aesenc %%xmm0, %%xmm3\n\t" "aesenc %%xmm0, %%xmm4\n\t" "aesenc %%xmm0, %%xmm8\n\t" "aesenc %%xmm0, %%xmm9\n\t" "aesenc %%xmm0, %%xmm10\n\t" "aesenc %%xmm0, %%xmm11\n\t" "movdqa 0x30(%[key]), %%xmm0\n\t" "aesenc %%xmm0, %%xmm1\n\t" "aesenc %%xmm0, %%xmm2\n\t" "aesenc %%xmm0, %%xmm3\n\t" "aesenc %%xmm0, %%xmm4\n\t" "aesenc %%xmm0, %%xmm8\n\t" "aesenc %%xmm0, %%xmm9\n\t" "aesenc %%xmm0, %%xmm10\n\t" "aesenc %%xmm0, %%xmm11\n\t" "movdqa 0x40(%[key]), %%xmm0\n\t" "aesenc %%xmm0, %%xmm1\n\t" "aesenc %%xmm0, %%xmm2\n\t" "aesenc %%xmm0, %%xmm3\n\t" "aesenc %%xmm0, %%xmm4\n\t" "aesenc %%xmm0, %%xmm8\n\t" "aesenc %%xmm0, %%xmm9\n\t" "aesenc %%xmm0, %%xmm10\n\t" "aesenc %%xmm0, %%xmm11\n\t" "movdqa 0x50(%[key]), %%xmm0\n\t" "aesenc %%xmm0, %%xmm1\n\t" "aesenc %%xmm0, %%xmm2\n\t" "aesenc %%xmm0, %%xmm3\n\t" "aesenc %%xmm0, %%xmm4\n\t" "aesenc %%xmm0, %%xmm8\n\t" "aesenc %%xmm0, %%xmm9\n\t" "aesenc %%xmm0, %%xmm10\n\t" "aesenc %%xmm0, %%xmm11\n\t" "movdqa 0x60(%[key]), %%xmm0\n\t" "aesenc %%xmm0, %%xmm1\n\t" "aesenc %%xmm0, %%xmm2\n\t" "aesenc %%xmm0, %%xmm3\n\t" "aesenc %%xmm0, %%xmm4\n\t" "aesenc %%xmm0, %%xmm8\n\t" "aesenc %%xmm0, %%xmm9\n\t" "aesenc %%xmm0, %%xmm10\n\t" "aesenc %%xmm0, %%xmm11\n\t" "movdqa 0x70(%[key]), %%xmm0\n\t" "aesenc %%xmm0, %%xmm1\n\t" "aesenc %%xmm0, %%xmm2\n\t" "aesenc %%xmm0, %%xmm3\n\t" "aesenc %%xmm0, %%xmm4\n\t" "aesenc %%xmm0, %%xmm8\n\t" "aesenc %%xmm0, %%xmm9\n\t" "aesenc %%xmm0, %%xmm10\n\t" "aesenc %%xmm0, %%xmm11\n\t" "movdqa 0x80(%[key]), %%xmm0\n\t" "aesenc %%xmm0, %%xmm1\n\t" "aesenc %%xmm0, %%xmm2\n\t" "aesenc %%xmm0, %%xmm3\n\t" "aesenc %%xmm0, %%xmm4\n\t" "aesenc %%xmm0, %%xmm8\n\t" "aesenc %%xmm0, %%xmm9\n\t" "aesenc %%xmm0, %%xmm10\n\t" "aesenc %%xmm0, %%xmm11\n\t" "movdqa 0x90(%[key]), %%xmm0\n\t" "aesenc %%xmm0, %%xmm1\n\t" "aesenc %%xmm0, %%xmm2\n\t" "aesenc %%xmm0, %%xmm3\n\t" "aesenc %%xmm0, %%xmm4\n\t" "aesenc %%xmm0, %%xmm8\n\t" "aesenc %%xmm0, %%xmm9\n\t" "aesenc %%xmm0, %%xmm10\n\t" "aesenc %%xmm0, %%xmm11\n\t" "movdqa 0xa0(%[key]), %%xmm0\n\t" "jb .Lenclast%=\n\t" "aesenc %%xmm0, %%xmm1\n\t" "aesenc %%xmm0, %%xmm2\n\t" "aesenc %%xmm0, %%xmm3\n\t" "aesenc %%xmm0, %%xmm4\n\t" "aesenc %%xmm0, %%xmm8\n\t" "aesenc %%xmm0, %%xmm9\n\t" "aesenc %%xmm0, %%xmm10\n\t" "aesenc %%xmm0, %%xmm11\n\t" "movdqa 0xb0(%[key]), %%xmm0\n\t" "aesenc %%xmm0, %%xmm1\n\t" "aesenc %%xmm0, %%xmm2\n\t" "aesenc %%xmm0, %%xmm3\n\t" "aesenc %%xmm0, %%xmm4\n\t" "aesenc %%xmm0, %%xmm8\n\t" "aesenc %%xmm0, %%xmm9\n\t" "aesenc %%xmm0, %%xmm10\n\t" "aesenc %%xmm0, %%xmm11\n\t" "movdqa 0xc0(%[key]), %%xmm0\n\t" "je .Lenclast%=\n\t" "aesenc %%xmm0, %%xmm1\n\t" "aesenc %%xmm0, %%xmm2\n\t" "aesenc %%xmm0, %%xmm3\n\t" "aesenc %%xmm0, %%xmm4\n\t" "aesenc %%xmm0, %%xmm8\n\t" "aesenc %%xmm0, %%xmm9\n\t" "aesenc %%xmm0, %%xmm10\n\t" "aesenc %%xmm0, %%xmm11\n\t" "movdqa 0xd0(%[key]), %%xmm0\n\t" "aesenc %%xmm0, %%xmm1\n\t" "aesenc %%xmm0, %%xmm2\n\t" "aesenc %%xmm0, %%xmm3\n\t" "aesenc %%xmm0, %%xmm4\n\t" "aesenc %%xmm0, %%xmm8\n\t" "aesenc %%xmm0, %%xmm9\n\t" "aesenc %%xmm0, %%xmm10\n\t" "aesenc %%xmm0, %%xmm11\n\t" "movdqa 0xe0(%[key]), %%xmm0\n\t" ".Lenclast%=:\n\t" : : [key] "r" (ctx->keyschenc), [rounds] "rm" (ctx->rounds) : "cc", "memory"); asm volatile ("pxor %%xmm0, %%xmm7\n\t" "pxor %%xmm0, %%xmm12\n\t" "pxor %%xmm0, %%xmm13\n\t" "pxor %%xmm0, %%xmm14\n\t" "aesenclast %%xmm7, %%xmm1\n\t" "aesenclast %%xmm12, %%xmm2\n\t" "aesenclast %%xmm13, %%xmm3\n\t" "aesenclast %%xmm14, %%xmm4\n\t" "movdqu 5*16(%[outbuf]), %%xmm12\n\t" "movdqu 6*16(%[outbuf]), %%xmm13\n\t" "movdqu 7*16(%[outbuf]), %%xmm14\n\t" "pxor %%xmm0, %%xmm15\n\t" "pxor %%xmm0, %%xmm12\n\t" "pxor %%xmm0, %%xmm13\n\t" "pxor %%xmm0, %%xmm14\n\t" "aesenclast %%xmm15, %%xmm8\n\t" "aesenclast %%xmm12, %%xmm9\n\t" "aesenclast %%xmm13, %%xmm10\n\t" "aesenclast %%xmm14, %%xmm11\n\t" "movdqu %%xmm1, 0*16(%[outbuf])\n\t" "movdqu %%xmm2, 1*16(%[outbuf])\n\t" "movdqu %%xmm3, 2*16(%[outbuf])\n\t" "movdqu %%xmm4, 3*16(%[outbuf])\n\t" "movdqu %%xmm8, 4*16(%[outbuf])\n\t" "movdqu %%xmm9, 5*16(%[outbuf])\n\t" "movdqu %%xmm10, 6*16(%[outbuf])\n\t" "movdqu %%xmm11, 7*16(%[outbuf])\n\t" : : [outbuf] "r" (outbuf) : "memory" ); outbuf += 8*BLOCKSIZE; inbuf += 8*BLOCKSIZE; } aesni_cleanup_8_15(); } #endif for ( ;nblocks >= 4; nblocks -= 4 ) { asm volatile ("pshufd $0x13, %%xmm5, %%xmm4\n\t" "movdqu %[inbuf0], %%xmm1\n\t" "pxor %%xmm5, %%xmm1\n\t" "movdqu %%xmm5, %[outbuf0]\n\t" "movdqa %%xmm4, %%xmm0\n\t" "paddd %%xmm4, %%xmm4\n\t" "psrad $31, %%xmm0\n\t" "paddq %%xmm5, %%xmm5\n\t" "pand %%xmm6, %%xmm0\n\t" "pxor %%xmm0, %%xmm5\n\t" : [outbuf0] "=m" (*(outbuf + 0 * 16)) : [inbuf0] "m" (*(inbuf + 0 * 16)) : "memory" ); asm volatile ("movdqu %[inbuf1], %%xmm2\n\t" "pxor %%xmm5, %%xmm2\n\t" "movdqu %%xmm5, %[outbuf1]\n\t" "movdqa %%xmm4, %%xmm0\n\t" "paddd %%xmm4, %%xmm4\n\t" "psrad $31, %%xmm0\n\t" "paddq %%xmm5, %%xmm5\n\t" "pand %%xmm6, %%xmm0\n\t" "pxor %%xmm0, %%xmm5\n\t" : [outbuf1] "=m" (*(outbuf + 1 * 16)) : [inbuf1] "m" (*(inbuf + 1 * 16)) : "memory" ); asm volatile ("movdqu %[inbuf2], %%xmm3\n\t" "pxor %%xmm5, %%xmm3\n\t" "movdqu %%xmm5, %[outbuf2]\n\t" "movdqa %%xmm4, %%xmm0\n\t" "paddd %%xmm4, %%xmm4\n\t" "psrad $31, %%xmm0\n\t" "paddq %%xmm5, %%xmm5\n\t" "pand %%xmm6, %%xmm0\n\t" "pxor %%xmm0, %%xmm5\n\t" : [outbuf2] "=m" (*(outbuf + 2 * 16)) : [inbuf2] "m" (*(inbuf + 2 * 16)) : "memory" ); asm volatile ("movdqa %%xmm4, %%xmm0\n\t" "movdqu %[inbuf3], %%xmm4\n\t" "pxor %%xmm5, %%xmm4\n\t" "movdqu %%xmm5, %[outbuf3]\n\t" "psrad $31, %%xmm0\n\t" "paddq %%xmm5, %%xmm5\n\t" "pand %%xmm6, %%xmm0\n\t" "pxor %%xmm0, %%xmm5\n\t" : [outbuf3] "=m" (*(outbuf + 3 * 16)) : [inbuf3] "m" (*(inbuf + 3 * 16)) : "memory" ); do_aesni_enc_vec4 (ctx); asm volatile ("movdqu %[outbuf0], %%xmm0\n\t" "pxor %%xmm0, %%xmm1\n\t" "movdqu %[outbuf1], %%xmm0\n\t" "movdqu %%xmm1, %[outbuf0]\n\t" "movdqu %[outbuf2], %%xmm1\n\t" "pxor %%xmm0, %%xmm2\n\t" "movdqu %[outbuf3], %%xmm0\n\t" "pxor %%xmm1, %%xmm3\n\t" "pxor %%xmm0, %%xmm4\n\t" "movdqu %%xmm2, %[outbuf1]\n\t" "movdqu %%xmm3, %[outbuf2]\n\t" "movdqu %%xmm4, %[outbuf3]\n\t" : [outbuf0] "+m" (*(outbuf + 0 * 16)), [outbuf1] "+m" (*(outbuf + 1 * 16)), [outbuf2] "+m" (*(outbuf + 2 * 16)), [outbuf3] "+m" (*(outbuf + 3 * 16)) : : "memory" ); outbuf += BLOCKSIZE * 4; inbuf += BLOCKSIZE * 4; } for ( ;nblocks; nblocks-- ) { asm volatile ("movdqu %[inbuf], %%xmm0\n\t" "pxor %%xmm5, %%xmm0\n\t" "movdqa %%xmm5, %%xmm4\n\t" "pshufd $0x13, %%xmm5, %%xmm1\n\t" "psrad $31, %%xmm1\n\t" "paddq %%xmm5, %%xmm5\n\t" "pand %%xmm6, %%xmm1\n\t" "pxor %%xmm1, %%xmm5\n\t" : : [inbuf] "m" (*inbuf) : "memory" ); do_aesni_enc (ctx); asm volatile ("pxor %%xmm4, %%xmm0\n\t" "movdqu %%xmm0, %[outbuf]\n\t" : [outbuf] "=m" (*outbuf) : : "memory" ); outbuf += BLOCKSIZE; inbuf += BLOCKSIZE; } asm volatile ("movdqu %%xmm5, %[tweak]\n\t" : [tweak] "=m" (*tweak) : : "memory" ); aesni_cleanup (); aesni_cleanup_2_7 (); } static void ASM_FUNC_ATTR _gcry_aes_aesni_xts_dec (RIJNDAEL_context *ctx, unsigned char *tweak, unsigned char *outbuf, const unsigned char *inbuf, size_t nblocks) { aesni_prepare_2_7_variable; aesni_prepare (); aesni_prepare_2_7 (); if ( !ctx->decryption_prepared ) { do_aesni_prepare_decryption ( ctx ); ctx->decryption_prepared = 1; } /* Preload Tweak */ asm volatile ("movdqu %[tweak], %%xmm5\n\t" "movdqa %[gfmul], %%xmm6\n\t" : : [tweak] "m" (*tweak), [gfmul] "m" (*xts_gfmul_const) : "memory" ); #ifdef __x86_64__ if (nblocks >= 8) { aesni_prepare_8_15_variable; aesni_prepare_8_15(); for ( ;nblocks >= 8 ; nblocks -= 8 ) { asm volatile ("pshufd $0x13, %%xmm5, %%xmm11\n\t" "movdqu %[inbuf0], %%xmm1\n\t" "pxor %%xmm5, %%xmm1\n\t" "movdqa %%xmm5, %%xmm7\n\t" "movdqa %%xmm11, %%xmm0\n\t" "paddd %%xmm11, %%xmm11\n\t" "psrad $31, %%xmm0\n\t" "paddq %%xmm5, %%xmm5\n\t" "pand %%xmm6, %%xmm0\n\t" "pxor %%xmm0, %%xmm5\n\t" : : [inbuf0] "m" (*(inbuf + 0 * 16)) : "memory" ); asm volatile ("movdqu %[inbuf1], %%xmm2\n\t" "pxor %%xmm5, %%xmm2\n\t" "movdqa %%xmm5, %%xmm12\n\t" "movdqa %%xmm11, %%xmm0\n\t" "paddd %%xmm11, %%xmm11\n\t" "psrad $31, %%xmm0\n\t" "paddq %%xmm5, %%xmm5\n\t" "pand %%xmm6, %%xmm0\n\t" "pxor %%xmm0, %%xmm5\n\t" : : [inbuf1] "m" (*(inbuf + 1 * 16)) : "memory" ); asm volatile ("movdqu %[inbuf2], %%xmm3\n\t" "pxor %%xmm5, %%xmm3\n\t" "movdqa %%xmm5, %%xmm13\n\t" "movdqa %%xmm11, %%xmm0\n\t" "paddd %%xmm11, %%xmm11\n\t" "psrad $31, %%xmm0\n\t" "paddq %%xmm5, %%xmm5\n\t" "pand %%xmm6, %%xmm0\n\t" "pxor %%xmm0, %%xmm5\n\t" : : [inbuf2] "m" (*(inbuf + 2 * 16)) : "memory" ); asm volatile ("movdqu %[inbuf3], %%xmm4\n\t" "pxor %%xmm5, %%xmm4\n\t" "movdqa %%xmm5, %%xmm14\n\t" "movdqa %%xmm11, %%xmm0\n\t" "paddd %%xmm11, %%xmm11\n\t" "psrad $31, %%xmm0\n\t" "paddq %%xmm5, %%xmm5\n\t" "pand %%xmm6, %%xmm0\n\t" "pxor %%xmm0, %%xmm5\n\t" : : [inbuf3] "m" (*(inbuf + 3 * 16)) : "memory" ); asm volatile ("movdqu %[inbuf4], %%xmm8\n\t" "pxor %%xmm5, %%xmm8\n\t" "movdqa %%xmm5, %%xmm15\n\t" "movdqa %%xmm11, %%xmm0\n\t" "paddd %%xmm11, %%xmm11\n\t" "psrad $31, %%xmm0\n\t" "paddq %%xmm5, %%xmm5\n\t" "pand %%xmm6, %%xmm0\n\t" "pxor %%xmm0, %%xmm5\n\t" : : [inbuf4] "m" (*(inbuf + 4 * 16)) : "memory" ); asm volatile ("movdqu %[inbuf5], %%xmm9\n\t" "pxor %%xmm5, %%xmm9\n\t" "movdqu %%xmm5, %[outbuf5]\n\t" "movdqa %%xmm11, %%xmm0\n\t" "paddd %%xmm11, %%xmm11\n\t" "psrad $31, %%xmm0\n\t" "paddq %%xmm5, %%xmm5\n\t" "pand %%xmm6, %%xmm0\n\t" "pxor %%xmm0, %%xmm5\n\t" : [outbuf5] "=m" (*(outbuf + 5 * 16)) : [inbuf5] "m" (*(inbuf + 5 * 16)) : "memory" ); asm volatile ("movdqu %[inbuf6], %%xmm10\n\t" "pxor %%xmm5, %%xmm10\n\t" "movdqu %%xmm5, %[outbuf6]\n\t" "movdqa %%xmm11, %%xmm0\n\t" "paddd %%xmm11, %%xmm11\n\t" "psrad $31, %%xmm0\n\t" "paddq %%xmm5, %%xmm5\n\t" "pand %%xmm6, %%xmm0\n\t" "pxor %%xmm0, %%xmm5\n\t" : [outbuf6] "=m" (*(outbuf + 6 * 16)) : [inbuf6] "m" (*(inbuf + 6 * 16)) : "memory" ); asm volatile ("movdqa %%xmm11, %%xmm0\n\t" "movdqu %[inbuf7], %%xmm11\n\t" "pxor %%xmm5, %%xmm11\n\t" "movdqu %%xmm5, %[outbuf7]\n\t" "psrad $31, %%xmm0\n\t" "paddq %%xmm5, %%xmm5\n\t" "pand %%xmm6, %%xmm0\n\t" "pxor %%xmm0, %%xmm5\n\t" : [outbuf7] "=m" (*(outbuf + 7 * 16)) : [inbuf7] "m" (*(inbuf + 7 * 16)) : "memory" ); asm volatile ("cmpl $12, %[rounds]\n\t" "movdqa (%[key]), %%xmm0\n\t" "pxor %%xmm0, %%xmm1\n\t" "pxor %%xmm0, %%xmm2\n\t" "pxor %%xmm0, %%xmm3\n\t" "pxor %%xmm0, %%xmm4\n\t" "pxor %%xmm0, %%xmm8\n\t" "pxor %%xmm0, %%xmm9\n\t" "pxor %%xmm0, %%xmm10\n\t" "pxor %%xmm0, %%xmm11\n\t" "movdqa 0x10(%[key]), %%xmm0\n\t" "aesdec %%xmm0, %%xmm1\n\t" "aesdec %%xmm0, %%xmm2\n\t" "aesdec %%xmm0, %%xmm3\n\t" "aesdec %%xmm0, %%xmm4\n\t" "aesdec %%xmm0, %%xmm8\n\t" "aesdec %%xmm0, %%xmm9\n\t" "aesdec %%xmm0, %%xmm10\n\t" "aesdec %%xmm0, %%xmm11\n\t" "movdqa 0x20(%[key]), %%xmm0\n\t" "aesdec %%xmm0, %%xmm1\n\t" "aesdec %%xmm0, %%xmm2\n\t" "aesdec %%xmm0, %%xmm3\n\t" "aesdec %%xmm0, %%xmm4\n\t" "aesdec %%xmm0, %%xmm8\n\t" "aesdec %%xmm0, %%xmm9\n\t" "aesdec %%xmm0, %%xmm10\n\t" "aesdec %%xmm0, %%xmm11\n\t" "movdqa 0x30(%[key]), %%xmm0\n\t" "aesdec %%xmm0, %%xmm1\n\t" "aesdec %%xmm0, %%xmm2\n\t" "aesdec %%xmm0, %%xmm3\n\t" "aesdec %%xmm0, %%xmm4\n\t" "aesdec %%xmm0, %%xmm8\n\t" "aesdec %%xmm0, %%xmm9\n\t" "aesdec %%xmm0, %%xmm10\n\t" "aesdec %%xmm0, %%xmm11\n\t" "movdqa 0x40(%[key]), %%xmm0\n\t" "aesdec %%xmm0, %%xmm1\n\t" "aesdec %%xmm0, %%xmm2\n\t" "aesdec %%xmm0, %%xmm3\n\t" "aesdec %%xmm0, %%xmm4\n\t" "aesdec %%xmm0, %%xmm8\n\t" "aesdec %%xmm0, %%xmm9\n\t" "aesdec %%xmm0, %%xmm10\n\t" "aesdec %%xmm0, %%xmm11\n\t" "movdqa 0x50(%[key]), %%xmm0\n\t" "aesdec %%xmm0, %%xmm1\n\t" "aesdec %%xmm0, %%xmm2\n\t" "aesdec %%xmm0, %%xmm3\n\t" "aesdec %%xmm0, %%xmm4\n\t" "aesdec %%xmm0, %%xmm8\n\t" "aesdec %%xmm0, %%xmm9\n\t" "aesdec %%xmm0, %%xmm10\n\t" "aesdec %%xmm0, %%xmm11\n\t" "movdqa 0x60(%[key]), %%xmm0\n\t" "aesdec %%xmm0, %%xmm1\n\t" "aesdec %%xmm0, %%xmm2\n\t" "aesdec %%xmm0, %%xmm3\n\t" "aesdec %%xmm0, %%xmm4\n\t" "aesdec %%xmm0, %%xmm8\n\t" "aesdec %%xmm0, %%xmm9\n\t" "aesdec %%xmm0, %%xmm10\n\t" "aesdec %%xmm0, %%xmm11\n\t" "movdqa 0x70(%[key]), %%xmm0\n\t" "aesdec %%xmm0, %%xmm1\n\t" "aesdec %%xmm0, %%xmm2\n\t" "aesdec %%xmm0, %%xmm3\n\t" "aesdec %%xmm0, %%xmm4\n\t" "aesdec %%xmm0, %%xmm8\n\t" "aesdec %%xmm0, %%xmm9\n\t" "aesdec %%xmm0, %%xmm10\n\t" "aesdec %%xmm0, %%xmm11\n\t" "movdqa 0x80(%[key]), %%xmm0\n\t" "aesdec %%xmm0, %%xmm1\n\t" "aesdec %%xmm0, %%xmm2\n\t" "aesdec %%xmm0, %%xmm3\n\t" "aesdec %%xmm0, %%xmm4\n\t" "aesdec %%xmm0, %%xmm8\n\t" "aesdec %%xmm0, %%xmm9\n\t" "aesdec %%xmm0, %%xmm10\n\t" "aesdec %%xmm0, %%xmm11\n\t" "movdqa 0x90(%[key]), %%xmm0\n\t" "aesdec %%xmm0, %%xmm1\n\t" "aesdec %%xmm0, %%xmm2\n\t" "aesdec %%xmm0, %%xmm3\n\t" "aesdec %%xmm0, %%xmm4\n\t" "aesdec %%xmm0, %%xmm8\n\t" "aesdec %%xmm0, %%xmm9\n\t" "aesdec %%xmm0, %%xmm10\n\t" "aesdec %%xmm0, %%xmm11\n\t" "movdqa 0xa0(%[key]), %%xmm0\n\t" "jb .Ldeclast%=\n\t" "aesdec %%xmm0, %%xmm1\n\t" "aesdec %%xmm0, %%xmm2\n\t" "aesdec %%xmm0, %%xmm3\n\t" "aesdec %%xmm0, %%xmm4\n\t" "aesdec %%xmm0, %%xmm8\n\t" "aesdec %%xmm0, %%xmm9\n\t" "aesdec %%xmm0, %%xmm10\n\t" "aesdec %%xmm0, %%xmm11\n\t" "movdqa 0xb0(%[key]), %%xmm0\n\t" "aesdec %%xmm0, %%xmm1\n\t" "aesdec %%xmm0, %%xmm2\n\t" "aesdec %%xmm0, %%xmm3\n\t" "aesdec %%xmm0, %%xmm4\n\t" "aesdec %%xmm0, %%xmm8\n\t" "aesdec %%xmm0, %%xmm9\n\t" "aesdec %%xmm0, %%xmm10\n\t" "aesdec %%xmm0, %%xmm11\n\t" "movdqa 0xc0(%[key]), %%xmm0\n\t" "je .Ldeclast%=\n\t" "aesdec %%xmm0, %%xmm1\n\t" "aesdec %%xmm0, %%xmm2\n\t" "aesdec %%xmm0, %%xmm3\n\t" "aesdec %%xmm0, %%xmm4\n\t" "aesdec %%xmm0, %%xmm8\n\t" "aesdec %%xmm0, %%xmm9\n\t" "aesdec %%xmm0, %%xmm10\n\t" "aesdec %%xmm0, %%xmm11\n\t" "movdqa 0xd0(%[key]), %%xmm0\n\t" "aesdec %%xmm0, %%xmm1\n\t" "aesdec %%xmm0, %%xmm2\n\t" "aesdec %%xmm0, %%xmm3\n\t" "aesdec %%xmm0, %%xmm4\n\t" "aesdec %%xmm0, %%xmm8\n\t" "aesdec %%xmm0, %%xmm9\n\t" "aesdec %%xmm0, %%xmm10\n\t" "aesdec %%xmm0, %%xmm11\n\t" "movdqa 0xe0(%[key]), %%xmm0\n\t" ".Ldeclast%=:\n\t" : : [key] "r" (ctx->keyschdec), [rounds] "rm" (ctx->rounds) : "cc", "memory"); asm volatile ("pxor %%xmm0, %%xmm7\n\t" "pxor %%xmm0, %%xmm12\n\t" "pxor %%xmm0, %%xmm13\n\t" "pxor %%xmm0, %%xmm14\n\t" "aesdeclast %%xmm7, %%xmm1\n\t" "aesdeclast %%xmm12, %%xmm2\n\t" "aesdeclast %%xmm13, %%xmm3\n\t" "aesdeclast %%xmm14, %%xmm4\n\t" "movdqu 5*16(%[outbuf]), %%xmm12\n\t" "movdqu 6*16(%[outbuf]), %%xmm13\n\t" "movdqu 7*16(%[outbuf]), %%xmm14\n\t" "pxor %%xmm0, %%xmm15\n\t" "pxor %%xmm0, %%xmm12\n\t" "pxor %%xmm0, %%xmm13\n\t" "pxor %%xmm0, %%xmm14\n\t" "aesdeclast %%xmm15, %%xmm8\n\t" "aesdeclast %%xmm12, %%xmm9\n\t" "aesdeclast %%xmm13, %%xmm10\n\t" "aesdeclast %%xmm14, %%xmm11\n\t" "movdqu %%xmm1, 0*16(%[outbuf])\n\t" "movdqu %%xmm2, 1*16(%[outbuf])\n\t" "movdqu %%xmm3, 2*16(%[outbuf])\n\t" "movdqu %%xmm4, 3*16(%[outbuf])\n\t" "movdqu %%xmm8, 4*16(%[outbuf])\n\t" "movdqu %%xmm9, 5*16(%[outbuf])\n\t" "movdqu %%xmm10, 6*16(%[outbuf])\n\t" "movdqu %%xmm11, 7*16(%[outbuf])\n\t" : : [outbuf] "r" (outbuf) : "memory" ); outbuf += 8*BLOCKSIZE; inbuf += 8*BLOCKSIZE; } aesni_cleanup_8_15(); } #endif for ( ;nblocks >= 4; nblocks -= 4 ) { asm volatile ("pshufd $0x13, %%xmm5, %%xmm4\n\t" "movdqu %[inbuf0], %%xmm1\n\t" "pxor %%xmm5, %%xmm1\n\t" "movdqu %%xmm5, %[outbuf0]\n\t" "movdqa %%xmm4, %%xmm0\n\t" "paddd %%xmm4, %%xmm4\n\t" "psrad $31, %%xmm0\n\t" "paddq %%xmm5, %%xmm5\n\t" "pand %%xmm6, %%xmm0\n\t" "pxor %%xmm0, %%xmm5\n\t" : [outbuf0] "=m" (*(outbuf + 0 * 16)) : [inbuf0] "m" (*(inbuf + 0 * 16)) : "memory" ); asm volatile ("movdqu %[inbuf1], %%xmm2\n\t" "pxor %%xmm5, %%xmm2\n\t" "movdqu %%xmm5, %[outbuf1]\n\t" "movdqa %%xmm4, %%xmm0\n\t" "paddd %%xmm4, %%xmm4\n\t" "psrad $31, %%xmm0\n\t" "paddq %%xmm5, %%xmm5\n\t" "pand %%xmm6, %%xmm0\n\t" "pxor %%xmm0, %%xmm5\n\t" : [outbuf1] "=m" (*(outbuf + 1 * 16)) : [inbuf1] "m" (*(inbuf + 1 * 16)) : "memory" ); asm volatile ("movdqu %[inbuf2], %%xmm3\n\t" "pxor %%xmm5, %%xmm3\n\t" "movdqu %%xmm5, %[outbuf2]\n\t" "movdqa %%xmm4, %%xmm0\n\t" "paddd %%xmm4, %%xmm4\n\t" "psrad $31, %%xmm0\n\t" "paddq %%xmm5, %%xmm5\n\t" "pand %%xmm6, %%xmm0\n\t" "pxor %%xmm0, %%xmm5\n\t" : [outbuf2] "=m" (*(outbuf + 2 * 16)) : [inbuf2] "m" (*(inbuf + 2 * 16)) : "memory" ); asm volatile ("movdqa %%xmm4, %%xmm0\n\t" "movdqu %[inbuf3], %%xmm4\n\t" "pxor %%xmm5, %%xmm4\n\t" "movdqu %%xmm5, %[outbuf3]\n\t" "psrad $31, %%xmm0\n\t" "paddq %%xmm5, %%xmm5\n\t" "pand %%xmm6, %%xmm0\n\t" "pxor %%xmm0, %%xmm5\n\t" : [outbuf3] "=m" (*(outbuf + 3 * 16)) : [inbuf3] "m" (*(inbuf + 3 * 16)) : "memory" ); do_aesni_dec_vec4 (ctx); asm volatile ("movdqu %[outbuf0], %%xmm0\n\t" "pxor %%xmm0, %%xmm1\n\t" "movdqu %[outbuf1], %%xmm0\n\t" "movdqu %%xmm1, %[outbuf0]\n\t" "movdqu %[outbuf2], %%xmm1\n\t" "pxor %%xmm0, %%xmm2\n\t" "movdqu %[outbuf3], %%xmm0\n\t" "pxor %%xmm1, %%xmm3\n\t" "pxor %%xmm0, %%xmm4\n\t" "movdqu %%xmm2, %[outbuf1]\n\t" "movdqu %%xmm3, %[outbuf2]\n\t" "movdqu %%xmm4, %[outbuf3]\n\t" : [outbuf0] "+m" (*(outbuf + 0 * 16)), [outbuf1] "+m" (*(outbuf + 1 * 16)), [outbuf2] "+m" (*(outbuf + 2 * 16)), [outbuf3] "+m" (*(outbuf + 3 * 16)) : : "memory" ); outbuf += BLOCKSIZE * 4; inbuf += BLOCKSIZE * 4; } for ( ;nblocks; nblocks-- ) { asm volatile ("movdqu %[inbuf], %%xmm0\n\t" "pxor %%xmm5, %%xmm0\n\t" "movdqa %%xmm5, %%xmm4\n\t" "pshufd $0x13, %%xmm5, %%xmm1\n\t" "psrad $31, %%xmm1\n\t" "paddq %%xmm5, %%xmm5\n\t" "pand %%xmm6, %%xmm1\n\t" "pxor %%xmm1, %%xmm5\n\t" : : [inbuf] "m" (*inbuf) : "memory" ); do_aesni_dec (ctx); asm volatile ("pxor %%xmm4, %%xmm0\n\t" "movdqu %%xmm0, %[outbuf]\n\t" : [outbuf] "=m" (*outbuf) : : "memory" ); outbuf += BLOCKSIZE; inbuf += BLOCKSIZE; } asm volatile ("movdqu %%xmm5, %[tweak]\n\t" : [tweak] "=m" (*tweak) : : "memory" ); aesni_cleanup (); aesni_cleanup_2_7 (); } void ASM_FUNC_ATTR _gcry_aes_aesni_xts_crypt (RIJNDAEL_context *ctx, unsigned char *tweak, unsigned char *outbuf, const unsigned char *inbuf, size_t nblocks, int encrypt) { if (encrypt) _gcry_aes_aesni_xts_enc(ctx, tweak, outbuf, inbuf, nblocks); else _gcry_aes_aesni_xts_dec(ctx, tweak, outbuf, inbuf, nblocks); } #if __clang__ # pragma clang attribute pop #endif #endif /* USE_AESNI */ diff --git a/cipher/rijndael-vaes-avx2-amd64.S b/cipher/rijndael-vaes-avx2-amd64.S index c4deea9b..d4ecf59f 100644 --- a/cipher/rijndael-vaes-avx2-amd64.S +++ b/cipher/rijndael-vaes-avx2-amd64.S @@ -1,2693 +1,3021 @@ /* VAES/AVX2 AMD64 accelerated AES for Libgcrypt * Copyright (C) 2021 Jussi Kivilinna * * This file is part of Libgcrypt. * * Libgcrypt is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * Libgcrypt is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this program; if not, see . */ #if defined(__x86_64__) #include #if (defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) || \ defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS)) && \ defined(ENABLE_AESNI_SUPPORT) && defined(ENABLE_AVX2_SUPPORT) && \ defined(HAVE_GCC_INLINE_ASM_VAES_VPCLMUL) #include "asm-common-amd64.h" .text /********************************************************************** helper macros **********************************************************************/ #define no(...) /*_*/ #define yes(...) __VA_ARGS__ #define AES_OP8(op, key, b0, b1, b2, b3, b4, b5, b6, b7) \ op key, b0, b0; \ op key, b1, b1; \ op key, b2, b2; \ op key, b3, b3; \ op key, b4, b4; \ op key, b5, b5; \ op key, b6, b6; \ op key, b7, b7; #define VAESENC8(key, b0, b1, b2, b3, b4, b5, b6, b7) \ AES_OP8(vaesenc, key, b0, b1, b2, b3, b4, b5, b6, b7) #define VAESDEC8(key, b0, b1, b2, b3, b4, b5, b6, b7) \ AES_OP8(vaesdec, key, b0, b1, b2, b3, b4, b5, b6, b7) #define XOR8(key, b0, b1, b2, b3, b4, b5, b6, b7) \ AES_OP8(vpxor, key, b0, b1, b2, b3, b4, b5, b6, b7) #define AES_OP4(op, key, b0, b1, b2, b3) \ op key, b0, b0; \ op key, b1, b1; \ op key, b2, b2; \ op key, b3, b3; #define VAESENC4(key, b0, b1, b2, b3) \ AES_OP4(vaesenc, key, b0, b1, b2, b3) #define VAESDEC4(key, b0, b1, b2, b3) \ AES_OP4(vaesdec, key, b0, b1, b2, b3) #define XOR4(key, b0, b1, b2, b3) \ AES_OP4(vpxor, key, b0, b1, b2, b3) #define AES_OP2(op, key, b0, b1) \ op key, b0, b0; \ op key, b1, b1; #define VAESENC2(key, b0, b1) \ AES_OP2(vaesenc, key, b0, b1) #define VAESDEC2(key, b0, b1) \ AES_OP2(vaesdec, key, b0, b1) #define XOR2(key, b0, b1) \ AES_OP2(vpxor, key, b0, b1) /********************************************************************** CBC-mode decryption **********************************************************************/ ELF(.type _gcry_vaes_avx2_cbc_dec_amd64,@function) .globl _gcry_vaes_avx2_cbc_dec_amd64 _gcry_vaes_avx2_cbc_dec_amd64: /* input: * %rdi: round keys * %rsi: iv * %rdx: dst * %rcx: src * %r8: nblocks * %r9: nrounds */ CFI_STARTPROC(); /* Load IV. */ vmovdqu (%rsi), %xmm15; /* Process 16 blocks per loop. */ .align 8 .Lcbc_dec_blk16: cmpq $16, %r8; jb .Lcbc_dec_blk8; leaq -16(%r8), %r8; /* Load input and xor first key. Update IV. */ vbroadcasti128 (0 * 16)(%rdi), %ymm8; vmovdqu (0 * 16)(%rcx), %ymm0; vmovdqu (2 * 16)(%rcx), %ymm1; vmovdqu (4 * 16)(%rcx), %ymm2; vmovdqu (6 * 16)(%rcx), %ymm3; vmovdqu (8 * 16)(%rcx), %ymm4; vmovdqu (10 * 16)(%rcx), %ymm5; vmovdqu (12 * 16)(%rcx), %ymm6; vmovdqu (14 * 16)(%rcx), %ymm7; vpxor %ymm8, %ymm0, %ymm0; vpxor %ymm8, %ymm1, %ymm1; vpxor %ymm8, %ymm2, %ymm2; vpxor %ymm8, %ymm3, %ymm3; vpxor %ymm8, %ymm4, %ymm4; vpxor %ymm8, %ymm5, %ymm5; vpxor %ymm8, %ymm6, %ymm6; vpxor %ymm8, %ymm7, %ymm7; vbroadcasti128 (1 * 16)(%rdi), %ymm8; vinserti128 $1, (0 * 16)(%rcx), %ymm15, %ymm9; vmovdqu (1 * 16)(%rcx), %ymm10; vmovdqu (3 * 16)(%rcx), %ymm11; vmovdqu (5 * 16)(%rcx), %ymm12; vmovdqu (7 * 16)(%rcx), %ymm13; vmovdqu (9 * 16)(%rcx), %ymm14; vmovdqu (15 * 16)(%rcx), %xmm15; leaq (16 * 16)(%rcx), %rcx; /* AES rounds */ VAESDEC8(%ymm8, %ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7); vbroadcasti128 (2 * 16)(%rdi), %ymm8; VAESDEC8(%ymm8, %ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7); vbroadcasti128 (3 * 16)(%rdi), %ymm8; VAESDEC8(%ymm8, %ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7); vbroadcasti128 (4 * 16)(%rdi), %ymm8; VAESDEC8(%ymm8, %ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7); vbroadcasti128 (5 * 16)(%rdi), %ymm8; VAESDEC8(%ymm8, %ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7); vbroadcasti128 (6 * 16)(%rdi), %ymm8; VAESDEC8(%ymm8, %ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7); vbroadcasti128 (7 * 16)(%rdi), %ymm8; VAESDEC8(%ymm8, %ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7); vbroadcasti128 (8 * 16)(%rdi), %ymm8; VAESDEC8(%ymm8, %ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7); vbroadcasti128 (9 * 16)(%rdi), %ymm8; VAESDEC8(%ymm8, %ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7); vbroadcasti128 (10 * 16)(%rdi), %ymm8; cmpl $12, %r9d; jb .Lcbc_dec_blk16_last; VAESDEC8(%ymm8, %ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7); vbroadcasti128 (11 * 16)(%rdi), %ymm8; VAESDEC8(%ymm8, %ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7); vbroadcasti128 (12 * 16)(%rdi), %ymm8; jz .Lcbc_dec_blk16_last; VAESDEC8(%ymm8, %ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7); vbroadcasti128 (13 * 16)(%rdi), %ymm8; VAESDEC8(%ymm8, %ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7); vbroadcasti128 (14 * 16)(%rdi), %ymm8; /* Last round and output handling. */ .Lcbc_dec_blk16_last: vpxor %ymm8, %ymm9, %ymm9; vpxor %ymm8, %ymm10, %ymm10; vpxor %ymm8, %ymm11, %ymm11; vpxor %ymm8, %ymm12, %ymm12; vpxor %ymm8, %ymm13, %ymm13; vpxor %ymm8, %ymm14, %ymm14; vaesdeclast %ymm9, %ymm0, %ymm0; vaesdeclast %ymm10, %ymm1, %ymm1; vpxor (-5 * 16)(%rcx), %ymm8, %ymm9; vpxor (-3 * 16)(%rcx), %ymm8, %ymm10; vaesdeclast %ymm11, %ymm2, %ymm2; vaesdeclast %ymm12, %ymm3, %ymm3; vaesdeclast %ymm13, %ymm4, %ymm4; vaesdeclast %ymm14, %ymm5, %ymm5; vaesdeclast %ymm9, %ymm6, %ymm6; vaesdeclast %ymm10, %ymm7, %ymm7; vmovdqu %ymm0, (0 * 16)(%rdx); vmovdqu %ymm1, (2 * 16)(%rdx); vmovdqu %ymm2, (4 * 16)(%rdx); vmovdqu %ymm3, (6 * 16)(%rdx); vmovdqu %ymm4, (8 * 16)(%rdx); vmovdqu %ymm5, (10 * 16)(%rdx); vmovdqu %ymm6, (12 * 16)(%rdx); vmovdqu %ymm7, (14 * 16)(%rdx); leaq (16 * 16)(%rdx), %rdx; jmp .Lcbc_dec_blk16; /* Handle trailing eight blocks. */ .align 8 .Lcbc_dec_blk8: cmpq $8, %r8; jb .Lcbc_dec_blk4; leaq -8(%r8), %r8; /* Load input and xor first key. Update IV. */ vbroadcasti128 (0 * 16)(%rdi), %ymm4; vmovdqu (0 * 16)(%rcx), %ymm0; vmovdqu (2 * 16)(%rcx), %ymm1; vmovdqu (4 * 16)(%rcx), %ymm2; vmovdqu (6 * 16)(%rcx), %ymm3; vpxor %ymm4, %ymm0, %ymm0; vpxor %ymm4, %ymm1, %ymm1; vpxor %ymm4, %ymm2, %ymm2; vpxor %ymm4, %ymm3, %ymm3; vbroadcasti128 (1 * 16)(%rdi), %ymm4; vinserti128 $1, (0 * 16)(%rcx), %ymm15, %ymm10; vmovdqu (1 * 16)(%rcx), %ymm11; vmovdqu (3 * 16)(%rcx), %ymm12; vmovdqu (5 * 16)(%rcx), %ymm13; vmovdqu (7 * 16)(%rcx), %xmm15; leaq (8 * 16)(%rcx), %rcx; /* AES rounds */ VAESDEC4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3); vbroadcasti128 (2 * 16)(%rdi), %ymm4; VAESDEC4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3); vbroadcasti128 (3 * 16)(%rdi), %ymm4; VAESDEC4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3); vbroadcasti128 (4 * 16)(%rdi), %ymm4; VAESDEC4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3); vbroadcasti128 (5 * 16)(%rdi), %ymm4; VAESDEC4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3); vbroadcasti128 (6 * 16)(%rdi), %ymm4; VAESDEC4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3); vbroadcasti128 (7 * 16)(%rdi), %ymm4; VAESDEC4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3); vbroadcasti128 (8 * 16)(%rdi), %ymm4; VAESDEC4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3); vbroadcasti128 (9 * 16)(%rdi), %ymm4; VAESDEC4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3); vbroadcasti128 (10 * 16)(%rdi), %ymm4; cmpl $12, %r9d; jb .Lcbc_dec_blk8_last; VAESDEC4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3); vbroadcasti128 (11 * 16)(%rdi), %ymm4; VAESDEC4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3); vbroadcasti128 (12 * 16)(%rdi), %ymm4; jz .Lcbc_dec_blk8_last; VAESDEC4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3); vbroadcasti128 (13 * 16)(%rdi), %ymm4; VAESDEC4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3); vbroadcasti128 (14 * 16)(%rdi), %ymm4; /* Last round and output handling. */ .Lcbc_dec_blk8_last: vpxor %ymm4, %ymm10, %ymm10; vpxor %ymm4, %ymm11, %ymm11; vpxor %ymm4, %ymm12, %ymm12; vpxor %ymm4, %ymm13, %ymm13; vaesdeclast %ymm10, %ymm0, %ymm0; vaesdeclast %ymm11, %ymm1, %ymm1; vaesdeclast %ymm12, %ymm2, %ymm2; vaesdeclast %ymm13, %ymm3, %ymm3; vmovdqu %ymm0, (0 * 16)(%rdx); vmovdqu %ymm1, (2 * 16)(%rdx); vmovdqu %ymm2, (4 * 16)(%rdx); vmovdqu %ymm3, (6 * 16)(%rdx); leaq (8 * 16)(%rdx), %rdx; /* Handle trailing four blocks. */ .align 8 .Lcbc_dec_blk4: cmpq $4, %r8; jb .Lcbc_dec_blk1; leaq -4(%r8), %r8; /* Load input and xor first key. Update IV. */ vbroadcasti128 (0 * 16)(%rdi), %ymm4; vmovdqu (0 * 16)(%rcx), %ymm0; vmovdqu (2 * 16)(%rcx), %ymm1; vpxor %ymm4, %ymm0, %ymm0; vpxor %ymm4, %ymm1, %ymm1; vbroadcasti128 (1 * 16)(%rdi), %ymm4; vinserti128 $1, (0 * 16)(%rcx), %ymm15, %ymm10; vmovdqu (1 * 16)(%rcx), %ymm11; vmovdqu (3 * 16)(%rcx), %xmm15; leaq (4 * 16)(%rcx), %rcx; /* AES rounds */ VAESDEC2(%ymm4, %ymm0, %ymm1); vbroadcasti128 (2 * 16)(%rdi), %ymm4; VAESDEC2(%ymm4, %ymm0, %ymm1); vbroadcasti128 (3 * 16)(%rdi), %ymm4; VAESDEC2(%ymm4, %ymm0, %ymm1); vbroadcasti128 (4 * 16)(%rdi), %ymm4; VAESDEC2(%ymm4, %ymm0, %ymm1); vbroadcasti128 (5 * 16)(%rdi), %ymm4; VAESDEC2(%ymm4, %ymm0, %ymm1); vbroadcasti128 (6 * 16)(%rdi), %ymm4; VAESDEC2(%ymm4, %ymm0, %ymm1); vbroadcasti128 (7 * 16)(%rdi), %ymm4; VAESDEC2(%ymm4, %ymm0, %ymm1); vbroadcasti128 (8 * 16)(%rdi), %ymm4; VAESDEC2(%ymm4, %ymm0, %ymm1); vbroadcasti128 (9 * 16)(%rdi), %ymm4; VAESDEC2(%ymm4, %ymm0, %ymm1); vbroadcasti128 (10 * 16)(%rdi), %ymm4; cmpl $12, %r9d; jb .Lcbc_dec_blk4_last; VAESDEC2(%ymm4, %ymm0, %ymm1); vbroadcasti128 (11 * 16)(%rdi), %ymm4; VAESDEC2(%ymm4, %ymm0, %ymm1); vbroadcasti128 (12 * 16)(%rdi), %ymm4; jz .Lcbc_dec_blk4_last; VAESDEC2(%ymm4, %ymm0, %ymm1); vbroadcasti128 (13 * 16)(%rdi), %ymm4; VAESDEC2(%ymm4, %ymm0, %ymm1); vbroadcasti128 (14 * 16)(%rdi), %ymm4; /* Last round and output handling. */ .Lcbc_dec_blk4_last: vpxor %ymm4, %ymm10, %ymm10; vpxor %ymm4, %ymm11, %ymm11; vaesdeclast %ymm10, %ymm0, %ymm0; vaesdeclast %ymm11, %ymm1, %ymm1; vmovdqu %ymm0, (0 * 16)(%rdx); vmovdqu %ymm1, (2 * 16)(%rdx); leaq (4 * 16)(%rdx), %rdx; /* Process trailing one to three blocks, one per loop. */ .align 8 .Lcbc_dec_blk1: cmpq $1, %r8; jb .Ldone_cbc_dec; leaq -1(%r8), %r8; /* Load input. */ vmovdqu (%rcx), %xmm2; leaq 16(%rcx), %rcx; /* Xor first key. */ vpxor (0 * 16)(%rdi), %xmm2, %xmm0; /* AES rounds. */ vaesdec (1 * 16)(%rdi), %xmm0, %xmm0; vaesdec (2 * 16)(%rdi), %xmm0, %xmm0; vaesdec (3 * 16)(%rdi), %xmm0, %xmm0; vaesdec (4 * 16)(%rdi), %xmm0, %xmm0; vaesdec (5 * 16)(%rdi), %xmm0, %xmm0; vaesdec (6 * 16)(%rdi), %xmm0, %xmm0; vaesdec (7 * 16)(%rdi), %xmm0, %xmm0; vaesdec (8 * 16)(%rdi), %xmm0, %xmm0; vaesdec (9 * 16)(%rdi), %xmm0, %xmm0; vmovdqa (10 * 16)(%rdi), %xmm1; cmpl $12, %r9d; jb .Lcbc_dec_blk1_last; vaesdec %xmm1, %xmm0, %xmm0; vaesdec (11 * 16)(%rdi), %xmm0, %xmm0; vmovdqa (12 * 16)(%rdi), %xmm1; jz .Lcbc_dec_blk1_last; vaesdec %xmm1, %xmm0, %xmm0; vaesdec (13 * 16)(%rdi), %xmm0, %xmm0; vmovdqa (14 * 16)(%rdi), %xmm1; /* Last round and output handling. */ .Lcbc_dec_blk1_last: vpxor %xmm1, %xmm15, %xmm15; vaesdeclast %xmm15, %xmm0, %xmm0; vmovdqa %xmm2, %xmm15; vmovdqu %xmm0, (%rdx); leaq 16(%rdx), %rdx; jmp .Lcbc_dec_blk1; .align 8 .Ldone_cbc_dec: /* Store IV. */ vmovdqu %xmm15, (%rsi); vzeroall; ret CFI_ENDPROC(); ELF(.size _gcry_vaes_avx2_cbc_dec_amd64,.-_gcry_vaes_avx2_cbc_dec_amd64) /********************************************************************** CFB-mode decryption **********************************************************************/ ELF(.type _gcry_vaes_avx2_cfb_dec_amd64,@function) .globl _gcry_vaes_avx2_cfb_dec_amd64 _gcry_vaes_avx2_cfb_dec_amd64: /* input: * %rdi: round keys * %rsi: iv * %rdx: dst * %rcx: src * %r8: nblocks * %r9: nrounds */ CFI_STARTPROC(); /* Load IV. */ vmovdqu (%rsi), %xmm15; /* Process 16 blocks per loop. */ .align 8 .Lcfb_dec_blk16: cmpq $16, %r8; jb .Lcfb_dec_blk8; leaq -16(%r8), %r8; /* Load input and xor first key. Update IV. */ vbroadcasti128 (0 * 16)(%rdi), %ymm8; vinserti128 $1, (0 * 16)(%rcx), %ymm15, %ymm0; vmovdqu (1 * 16)(%rcx), %ymm1; vmovdqu (3 * 16)(%rcx), %ymm2; vmovdqu (5 * 16)(%rcx), %ymm3; vmovdqu (7 * 16)(%rcx), %ymm4; vmovdqu (9 * 16)(%rcx), %ymm5; vmovdqu (11 * 16)(%rcx), %ymm6; vmovdqu (13 * 16)(%rcx), %ymm7; vmovdqu (15 * 16)(%rcx), %xmm15; vpxor %ymm8, %ymm0, %ymm0; vpxor %ymm8, %ymm1, %ymm1; vpxor %ymm8, %ymm2, %ymm2; vpxor %ymm8, %ymm3, %ymm3; vpxor %ymm8, %ymm4, %ymm4; vpxor %ymm8, %ymm5, %ymm5; vpxor %ymm8, %ymm6, %ymm6; vpxor %ymm8, %ymm7, %ymm7; vbroadcasti128 (1 * 16)(%rdi), %ymm8; vmovdqu (0 * 16)(%rcx), %ymm9; vmovdqu (2 * 16)(%rcx), %ymm10; vmovdqu (4 * 16)(%rcx), %ymm11; vmovdqu (6 * 16)(%rcx), %ymm12; vmovdqu (8 * 16)(%rcx), %ymm13; vmovdqu (10 * 16)(%rcx), %ymm14; leaq (16 * 16)(%rcx), %rcx; /* AES rounds */ VAESENC8(%ymm8, %ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7); vbroadcasti128 (2 * 16)(%rdi), %ymm8; VAESENC8(%ymm8, %ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7); vbroadcasti128 (3 * 16)(%rdi), %ymm8; VAESENC8(%ymm8, %ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7); vbroadcasti128 (4 * 16)(%rdi), %ymm8; VAESENC8(%ymm8, %ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7); vbroadcasti128 (5 * 16)(%rdi), %ymm8; VAESENC8(%ymm8, %ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7); vbroadcasti128 (6 * 16)(%rdi), %ymm8; VAESENC8(%ymm8, %ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7); vbroadcasti128 (7 * 16)(%rdi), %ymm8; VAESENC8(%ymm8, %ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7); vbroadcasti128 (8 * 16)(%rdi), %ymm8; VAESENC8(%ymm8, %ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7); vbroadcasti128 (9 * 16)(%rdi), %ymm8; VAESENC8(%ymm8, %ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7); vbroadcasti128 (10 * 16)(%rdi), %ymm8; cmpl $12, %r9d; jb .Lcfb_dec_blk16_last; VAESENC8(%ymm8, %ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7); vbroadcasti128 (11 * 16)(%rdi), %ymm8; VAESENC8(%ymm8, %ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7); vbroadcasti128 (12 * 16)(%rdi), %ymm8; jz .Lcfb_dec_blk16_last; VAESENC8(%ymm8, %ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7); vbroadcasti128 (13 * 16)(%rdi), %ymm8; VAESENC8(%ymm8, %ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7); vbroadcasti128 (14 * 16)(%rdi), %ymm8; /* Last round and output handling. */ .Lcfb_dec_blk16_last: vpxor %ymm8, %ymm9, %ymm9; vpxor %ymm8, %ymm10, %ymm10; vpxor %ymm8, %ymm11, %ymm11; vpxor %ymm8, %ymm12, %ymm12; vpxor %ymm8, %ymm13, %ymm13; vpxor %ymm8, %ymm14, %ymm14; vaesenclast %ymm9, %ymm0, %ymm0; vaesenclast %ymm10, %ymm1, %ymm1; vpxor (-4 * 16)(%rcx), %ymm8, %ymm9; vpxor (-2 * 16)(%rcx), %ymm8, %ymm10; vaesenclast %ymm11, %ymm2, %ymm2; vaesenclast %ymm12, %ymm3, %ymm3; vaesenclast %ymm13, %ymm4, %ymm4; vaesenclast %ymm14, %ymm5, %ymm5; vaesenclast %ymm9, %ymm6, %ymm6; vaesenclast %ymm10, %ymm7, %ymm7; vmovdqu %ymm0, (0 * 16)(%rdx); vmovdqu %ymm1, (2 * 16)(%rdx); vmovdqu %ymm2, (4 * 16)(%rdx); vmovdqu %ymm3, (6 * 16)(%rdx); vmovdqu %ymm4, (8 * 16)(%rdx); vmovdqu %ymm5, (10 * 16)(%rdx); vmovdqu %ymm6, (12 * 16)(%rdx); vmovdqu %ymm7, (14 * 16)(%rdx); leaq (16 * 16)(%rdx), %rdx; jmp .Lcfb_dec_blk16; /* Handle trailing eight blocks. */ .align 8 .Lcfb_dec_blk8: cmpq $8, %r8; jb .Lcfb_dec_blk4; leaq -8(%r8), %r8; /* Load input and xor first key. Update IV. */ vbroadcasti128 (0 * 16)(%rdi), %ymm4; vinserti128 $1, (0 * 16)(%rcx), %ymm15, %ymm0; vmovdqu (1 * 16)(%rcx), %ymm1; vmovdqu (3 * 16)(%rcx), %ymm2; vmovdqu (5 * 16)(%rcx), %ymm3; vmovdqu (7 * 16)(%rcx), %xmm15; vpxor %ymm4, %ymm0, %ymm0; vpxor %ymm4, %ymm1, %ymm1; vpxor %ymm4, %ymm2, %ymm2; vpxor %ymm4, %ymm3, %ymm3; vbroadcasti128 (1 * 16)(%rdi), %ymm4; vmovdqu (0 * 16)(%rcx), %ymm10; vmovdqu (2 * 16)(%rcx), %ymm11; vmovdqu (4 * 16)(%rcx), %ymm12; vmovdqu (6 * 16)(%rcx), %ymm13; leaq (8 * 16)(%rcx), %rcx; /* AES rounds */ VAESENC4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3); vbroadcasti128 (2 * 16)(%rdi), %ymm4; VAESENC4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3); vbroadcasti128 (3 * 16)(%rdi), %ymm4; VAESENC4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3); vbroadcasti128 (4 * 16)(%rdi), %ymm4; VAESENC4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3); vbroadcasti128 (5 * 16)(%rdi), %ymm4; VAESENC4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3); vbroadcasti128 (6 * 16)(%rdi), %ymm4; VAESENC4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3); vbroadcasti128 (7 * 16)(%rdi), %ymm4; VAESENC4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3); vbroadcasti128 (8 * 16)(%rdi), %ymm4; VAESENC4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3); vbroadcasti128 (9 * 16)(%rdi), %ymm4; VAESENC4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3); vbroadcasti128 (10 * 16)(%rdi), %ymm4; cmpl $12, %r9d; jb .Lcfb_dec_blk8_last; VAESENC4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3); vbroadcasti128 (11 * 16)(%rdi), %ymm4; VAESENC4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3); vbroadcasti128 (12 * 16)(%rdi), %ymm4; jz .Lcfb_dec_blk8_last; VAESENC4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3); vbroadcasti128 (13 * 16)(%rdi), %ymm4; VAESENC4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3); vbroadcasti128 (14 * 16)(%rdi), %ymm4; /* Last round and output handling. */ .Lcfb_dec_blk8_last: vpxor %ymm4, %ymm10, %ymm10; vpxor %ymm4, %ymm11, %ymm11; vpxor %ymm4, %ymm12, %ymm12; vpxor %ymm4, %ymm13, %ymm13; vaesenclast %ymm10, %ymm0, %ymm0; vaesenclast %ymm11, %ymm1, %ymm1; vaesenclast %ymm12, %ymm2, %ymm2; vaesenclast %ymm13, %ymm3, %ymm3; vmovdqu %ymm0, (0 * 16)(%rdx); vmovdqu %ymm1, (2 * 16)(%rdx); vmovdqu %ymm2, (4 * 16)(%rdx); vmovdqu %ymm3, (6 * 16)(%rdx); leaq (8 * 16)(%rdx), %rdx; /* Handle trailing four blocks. */ .align 8 .Lcfb_dec_blk4: cmpq $4, %r8; jb .Lcfb_dec_blk1; leaq -4(%r8), %r8; /* Load input and xor first key. Update IV. */ vbroadcasti128 (0 * 16)(%rdi), %ymm4; vinserti128 $1, (0 * 16)(%rcx), %ymm15, %ymm0; vmovdqu (1 * 16)(%rcx), %ymm1; vmovdqu (3 * 16)(%rcx), %xmm15; vpxor %ymm4, %ymm0, %ymm0; vpxor %ymm4, %ymm1, %ymm1; vbroadcasti128 (1 * 16)(%rdi), %ymm4; vmovdqu (0 * 16)(%rcx), %ymm10; vmovdqu (2 * 16)(%rcx), %ymm11; leaq (4 * 16)(%rcx), %rcx; /* AES rounds */ VAESENC2(%ymm4, %ymm0, %ymm1); vbroadcasti128 (2 * 16)(%rdi), %ymm4; VAESENC2(%ymm4, %ymm0, %ymm1); vbroadcasti128 (3 * 16)(%rdi), %ymm4; VAESENC2(%ymm4, %ymm0, %ymm1); vbroadcasti128 (4 * 16)(%rdi), %ymm4; VAESENC2(%ymm4, %ymm0, %ymm1); vbroadcasti128 (5 * 16)(%rdi), %ymm4; VAESENC2(%ymm4, %ymm0, %ymm1); vbroadcasti128 (6 * 16)(%rdi), %ymm4; VAESENC2(%ymm4, %ymm0, %ymm1); vbroadcasti128 (7 * 16)(%rdi), %ymm4; VAESENC2(%ymm4, %ymm0, %ymm1); vbroadcasti128 (8 * 16)(%rdi), %ymm4; VAESENC2(%ymm4, %ymm0, %ymm1); vbroadcasti128 (9 * 16)(%rdi), %ymm4; VAESENC2(%ymm4, %ymm0, %ymm1); vbroadcasti128 (10 * 16)(%rdi), %ymm4; cmpl $12, %r9d; jb .Lcfb_dec_blk4_last; VAESENC2(%ymm4, %ymm0, %ymm1); vbroadcasti128 (11 * 16)(%rdi), %ymm4; VAESENC2(%ymm4, %ymm0, %ymm1); vbroadcasti128 (12 * 16)(%rdi), %ymm4; jz .Lcfb_dec_blk4_last; VAESENC2(%ymm4, %ymm0, %ymm1); vbroadcasti128 (13 * 16)(%rdi), %ymm4; VAESENC2(%ymm4, %ymm0, %ymm1); vbroadcasti128 (14 * 16)(%rdi), %ymm4; /* Last round and output handling. */ .Lcfb_dec_blk4_last: vpxor %ymm4, %ymm10, %ymm10; vpxor %ymm4, %ymm11, %ymm11; vaesenclast %ymm10, %ymm0, %ymm0; vaesenclast %ymm11, %ymm1, %ymm1; vmovdqu %ymm0, (0 * 16)(%rdx); vmovdqu %ymm1, (2 * 16)(%rdx); leaq (4 * 16)(%rdx), %rdx; /* Process trailing one to three blocks, one per loop. */ .align 8 .Lcfb_dec_blk1: cmpq $1, %r8; jb .Ldone_cfb_dec; leaq -1(%r8), %r8; /* Xor first key. */ vpxor (0 * 16)(%rdi), %xmm15, %xmm0; /* Load input as next IV. */ vmovdqu (%rcx), %xmm15; leaq 16(%rcx), %rcx; /* AES rounds. */ vaesenc (1 * 16)(%rdi), %xmm0, %xmm0; vaesenc (2 * 16)(%rdi), %xmm0, %xmm0; vaesenc (3 * 16)(%rdi), %xmm0, %xmm0; vaesenc (4 * 16)(%rdi), %xmm0, %xmm0; vaesenc (5 * 16)(%rdi), %xmm0, %xmm0; vaesenc (6 * 16)(%rdi), %xmm0, %xmm0; vaesenc (7 * 16)(%rdi), %xmm0, %xmm0; vaesenc (8 * 16)(%rdi), %xmm0, %xmm0; vaesenc (9 * 16)(%rdi), %xmm0, %xmm0; vmovdqa (10 * 16)(%rdi), %xmm1; cmpl $12, %r9d; jb .Lcfb_dec_blk1_last; vaesenc %xmm1, %xmm0, %xmm0; vaesenc (11 * 16)(%rdi), %xmm0, %xmm0; vmovdqa (12 * 16)(%rdi), %xmm1; jz .Lcfb_dec_blk1_last; vaesenc %xmm1, %xmm0, %xmm0; vaesenc (13 * 16)(%rdi), %xmm0, %xmm0; vmovdqa (14 * 16)(%rdi), %xmm1; /* Last round and output handling. */ .Lcfb_dec_blk1_last: vpxor %xmm15, %xmm1, %xmm1; vaesenclast %xmm1, %xmm0, %xmm0; vmovdqu %xmm0, (%rdx); leaq 16(%rdx), %rdx; jmp .Lcfb_dec_blk1; .align 8 .Ldone_cfb_dec: /* Store IV. */ vmovdqu %xmm15, (%rsi); vzeroall; ret CFI_ENDPROC(); ELF(.size _gcry_vaes_avx2_cfb_dec_amd64,.-_gcry_vaes_avx2_cfb_dec_amd64) /********************************************************************** CTR-mode encryption **********************************************************************/ ELF(.type _gcry_vaes_avx2_ctr_enc_amd64,@function) .globl _gcry_vaes_avx2_ctr_enc_amd64 _gcry_vaes_avx2_ctr_enc_amd64: /* input: * %rdi: round keys * %rsi: counter * %rdx: dst * %rcx: src * %r8: nblocks * %r9: nrounds */ CFI_STARTPROC(); movq 8(%rsi), %r10; movq 0(%rsi), %r11; bswapq %r10; bswapq %r11; vpcmpeqd %ymm15, %ymm15, %ymm15; vpsrldq $8, %ymm15, %ymm15; // 0:-1 vpaddq %ymm15, %ymm15, %ymm14; // 0:-2 vbroadcasti128 .Lbswap128_mask rRIP, %ymm13; #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; #define add2_le128(x, minus_one, minus_two, tmp1, tmp2) \ vpcmpeqq minus_one, x, tmp1; \ vpcmpeqq minus_two, x, tmp2; \ vpor tmp1, tmp2, tmp2; \ vpsubq minus_two, x, x; \ vpslldq $8, tmp2, tmp2; \ vpsubq tmp2, x, x; /* Process 16 blocks per loop. */ .align 8 .Lctr_enc_blk16: cmpq $16, %r8; jb .Lctr_enc_blk8; leaq -16(%r8), %r8; vbroadcasti128 (%rsi), %ymm7; vbroadcasti128 (0 * 16)(%rdi), %ymm8; /* detect if carry handling is needed */ addb $16, 15(%rsi); jc .Lctr_enc_blk16_handle_carry; /* Increment counters. */ vpaddb .Lbige_addb_0 rRIP, %ymm7, %ymm0; vpaddb .Lbige_addb_2 rRIP, %ymm7, %ymm1; vpaddb .Lbige_addb_4 rRIP, %ymm7, %ymm2; vpaddb .Lbige_addb_6 rRIP, %ymm7, %ymm3; vpaddb .Lbige_addb_8 rRIP, %ymm7, %ymm4; vpaddb .Lbige_addb_10 rRIP, %ymm7, %ymm5; vpaddb .Lbige_addb_12 rRIP, %ymm7, %ymm6; vpaddb .Lbige_addb_14 rRIP, %ymm7, %ymm7; leaq 16(%r10), %r10; .Lctr_enc_blk16_rounds: /* AES rounds */ XOR8(%ymm8, %ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7); vbroadcasti128 (1 * 16)(%rdi), %ymm8; VAESENC8(%ymm8, %ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7); vbroadcasti128 (2 * 16)(%rdi), %ymm8; VAESENC8(%ymm8, %ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7); vbroadcasti128 (3 * 16)(%rdi), %ymm8; VAESENC8(%ymm8, %ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7); vbroadcasti128 (4 * 16)(%rdi), %ymm8; VAESENC8(%ymm8, %ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7); vbroadcasti128 (5 * 16)(%rdi), %ymm8; VAESENC8(%ymm8, %ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7); vbroadcasti128 (6 * 16)(%rdi), %ymm8; VAESENC8(%ymm8, %ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7); vbroadcasti128 (7 * 16)(%rdi), %ymm8; VAESENC8(%ymm8, %ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7); vbroadcasti128 (8 * 16)(%rdi), %ymm8; VAESENC8(%ymm8, %ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7); vbroadcasti128 (9 * 16)(%rdi), %ymm8; VAESENC8(%ymm8, %ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7); vbroadcasti128 (10 * 16)(%rdi), %ymm8; cmpl $12, %r9d; jb .Lctr_enc_blk16_last; VAESENC8(%ymm8, %ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7); vbroadcasti128 (11 * 16)(%rdi), %ymm8; VAESENC8(%ymm8, %ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7); vbroadcasti128 (12 * 16)(%rdi), %ymm8; jz .Lctr_enc_blk16_last; VAESENC8(%ymm8, %ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7); vbroadcasti128 (13 * 16)(%rdi), %ymm8; VAESENC8(%ymm8, %ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7); vbroadcasti128 (14 * 16)(%rdi), %ymm8; /* Last round and output handling. */ .Lctr_enc_blk16_last: vpxor (0 * 16)(%rcx), %ymm8, %ymm9; /* Xor src to last round key. */ vpxor (2 * 16)(%rcx), %ymm8, %ymm10; vpxor (4 * 16)(%rcx), %ymm8, %ymm11; vpxor (6 * 16)(%rcx), %ymm8, %ymm12; vaesenclast %ymm9, %ymm0, %ymm0; vaesenclast %ymm10, %ymm1, %ymm1; vaesenclast %ymm11, %ymm2, %ymm2; vaesenclast %ymm12, %ymm3, %ymm3; vpxor (8 * 16)(%rcx), %ymm8, %ymm9; vpxor (10 * 16)(%rcx), %ymm8, %ymm10; vpxor (12 * 16)(%rcx), %ymm8, %ymm11; vpxor (14 * 16)(%rcx), %ymm8, %ymm8; leaq (16 * 16)(%rcx), %rcx; vaesenclast %ymm9, %ymm4, %ymm4; vaesenclast %ymm10, %ymm5, %ymm5; vaesenclast %ymm11, %ymm6, %ymm6; vaesenclast %ymm8, %ymm7, %ymm7; vmovdqu %ymm0, (0 * 16)(%rdx); vmovdqu %ymm1, (2 * 16)(%rdx); vmovdqu %ymm2, (4 * 16)(%rdx); vmovdqu %ymm3, (6 * 16)(%rdx); vmovdqu %ymm4, (8 * 16)(%rdx); vmovdqu %ymm5, (10 * 16)(%rdx); vmovdqu %ymm6, (12 * 16)(%rdx); vmovdqu %ymm7, (14 * 16)(%rdx); leaq (16 * 16)(%rdx), %rdx; jmp .Lctr_enc_blk16; .align 8 .Lctr_enc_blk16_handle_carry: /* Increment counters (handle carry). */ vpshufb %xmm13, %xmm7, %xmm1; /* be => le */ vmovdqa %xmm1, %xmm0; inc_le128(%xmm1, %xmm15, %xmm5); vinserti128 $1, %xmm1, %ymm0, %ymm7; /* ctr: +1:+0 */ vpshufb %ymm13, %ymm7, %ymm0; addq $16, %r10; adcq $0, %r11; bswapq %r10; bswapq %r11; movq %r10, 8(%rsi); movq %r11, 0(%rsi); bswapq %r10; bswapq %r11; add2_le128(%ymm7, %ymm15, %ymm14, %ymm9, %ymm10); /* ctr: +3:+2 */ vpshufb %ymm13, %ymm7, %ymm1; add2_le128(%ymm7, %ymm15, %ymm14, %ymm9, %ymm10); /* ctr: +5:+4 */ vpshufb %ymm13, %ymm7, %ymm2; add2_le128(%ymm7, %ymm15, %ymm14, %ymm9, %ymm10); /* ctr: +7:+6 */ vpshufb %ymm13, %ymm7, %ymm3; add2_le128(%ymm7, %ymm15, %ymm14, %ymm9, %ymm10); /* ctr: +9:+8 */ vpshufb %ymm13, %ymm7, %ymm4; add2_le128(%ymm7, %ymm15, %ymm14, %ymm9, %ymm10); /* ctr: +11:+10 */ vpshufb %ymm13, %ymm7, %ymm5; add2_le128(%ymm7, %ymm15, %ymm14, %ymm9, %ymm10); /* ctr: +13:+12 */ vpshufb %ymm13, %ymm7, %ymm6; add2_le128(%ymm7, %ymm15, %ymm14, %ymm9, %ymm10); /* ctr: +15:+14 */ vpshufb %ymm13, %ymm7, %ymm7; jmp .Lctr_enc_blk16_rounds; /* Handle trailing eight blocks. */ .align 8 .Lctr_enc_blk8: cmpq $8, %r8; jb .Lctr_enc_blk4; leaq -8(%r8), %r8; vbroadcasti128 (%rsi), %ymm3; vbroadcasti128 (0 * 16)(%rdi), %ymm4; /* detect if carry handling is needed */ addb $8, 15(%rsi); jc .Lctr_enc_blk8_handle_carry; /* Increment counters. */ vpaddb .Lbige_addb_0 rRIP, %ymm3, %ymm0; vpaddb .Lbige_addb_2 rRIP, %ymm3, %ymm1; vpaddb .Lbige_addb_4 rRIP, %ymm3, %ymm2; vpaddb .Lbige_addb_6 rRIP, %ymm3, %ymm3; leaq 8(%r10), %r10; .Lctr_enc_blk8_rounds: /* AES rounds */ XOR4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3); vbroadcasti128 (1 * 16)(%rdi), %ymm4; VAESENC4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3); vbroadcasti128 (2 * 16)(%rdi), %ymm4; VAESENC4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3); vbroadcasti128 (3 * 16)(%rdi), %ymm4; VAESENC4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3); vbroadcasti128 (4 * 16)(%rdi), %ymm4; VAESENC4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3); vbroadcasti128 (5 * 16)(%rdi), %ymm4; VAESENC4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3); vbroadcasti128 (6 * 16)(%rdi), %ymm4; VAESENC4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3); vbroadcasti128 (7 * 16)(%rdi), %ymm4; VAESENC4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3); vbroadcasti128 (8 * 16)(%rdi), %ymm4; VAESENC4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3); vbroadcasti128 (9 * 16)(%rdi), %ymm4; VAESENC4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3); vbroadcasti128 (10 * 16)(%rdi), %ymm4; cmpl $12, %r9d; jb .Lctr_enc_blk8_last; VAESENC4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3); vbroadcasti128 (11 * 16)(%rdi), %ymm4; VAESENC4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3); vbroadcasti128 (12 * 16)(%rdi), %ymm4; jz .Lctr_enc_blk8_last; VAESENC4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3); vbroadcasti128 (13 * 16)(%rdi), %ymm4; VAESENC4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3); vbroadcasti128 (14 * 16)(%rdi), %ymm4; /* Last round and output handling. */ .Lctr_enc_blk8_last: vpxor (0 * 16)(%rcx), %ymm4, %ymm5; /* Xor src to last round key. */ vpxor (2 * 16)(%rcx), %ymm4, %ymm6; vpxor (4 * 16)(%rcx), %ymm4, %ymm7; vpxor (6 * 16)(%rcx), %ymm4, %ymm4; leaq (8 * 16)(%rcx), %rcx; vaesenclast %ymm5, %ymm0, %ymm0; vaesenclast %ymm6, %ymm1, %ymm1; vaesenclast %ymm7, %ymm2, %ymm2; vaesenclast %ymm4, %ymm3, %ymm3; vmovdqu %ymm0, (0 * 16)(%rdx); vmovdqu %ymm1, (2 * 16)(%rdx); vmovdqu %ymm2, (4 * 16)(%rdx); vmovdqu %ymm3, (6 * 16)(%rdx); leaq (8 * 16)(%rdx), %rdx; jmp .Lctr_enc_blk4; .align 8 .Lctr_enc_blk8_handle_carry: /* Increment counters (handle carry). */ vpshufb %xmm13, %xmm3, %xmm1; /* be => le */ vmovdqa %xmm1, %xmm0; inc_le128(%xmm1, %xmm15, %xmm5); vinserti128 $1, %xmm1, %ymm0, %ymm3; /* ctr: +1:+0 */ vpshufb %ymm13, %ymm3, %ymm0; addq $8, %r10; adcq $0, %r11; bswapq %r10; bswapq %r11; movq %r10, 8(%rsi); movq %r11, 0(%rsi); bswapq %r10; bswapq %r11; add2_le128(%ymm3, %ymm15, %ymm14, %ymm5, %ymm6); /* ctr: +3:+2 */ vpshufb %ymm13, %ymm3, %ymm1; add2_le128(%ymm3, %ymm15, %ymm14, %ymm5, %ymm6); /* ctr: +5:+4 */ vpshufb %ymm13, %ymm3, %ymm2; add2_le128(%ymm3, %ymm15, %ymm14, %ymm5, %ymm6); /* ctr: +7:+6 */ vpshufb %ymm13, %ymm3, %ymm3; jmp .Lctr_enc_blk8_rounds; /* Handle trailing four blocks. */ .align 8 .Lctr_enc_blk4: cmpq $4, %r8; jb .Lctr_enc_blk1; leaq -4(%r8), %r8; vbroadcasti128 (%rsi), %ymm3; vbroadcasti128 (0 * 16)(%rdi), %ymm4; /* detect if carry handling is needed */ addb $4, 15(%rsi); jc .Lctr_enc_blk4_handle_carry; /* Increment counters. */ vpaddb .Lbige_addb_0 rRIP, %ymm3, %ymm0; vpaddb .Lbige_addb_2 rRIP, %ymm3, %ymm1; leaq 4(%r10), %r10; .Lctr_enc_blk4_rounds: /* AES rounds */ XOR2(%ymm4, %ymm0, %ymm1); vbroadcasti128 (1 * 16)(%rdi), %ymm4; VAESENC2(%ymm4, %ymm0, %ymm1); vbroadcasti128 (2 * 16)(%rdi), %ymm4; VAESENC2(%ymm4, %ymm0, %ymm1); vbroadcasti128 (3 * 16)(%rdi), %ymm4; VAESENC2(%ymm4, %ymm0, %ymm1); vbroadcasti128 (4 * 16)(%rdi), %ymm4; VAESENC2(%ymm4, %ymm0, %ymm1); vbroadcasti128 (5 * 16)(%rdi), %ymm4; VAESENC2(%ymm4, %ymm0, %ymm1); vbroadcasti128 (6 * 16)(%rdi), %ymm4; VAESENC2(%ymm4, %ymm0, %ymm1); vbroadcasti128 (7 * 16)(%rdi), %ymm4; VAESENC2(%ymm4, %ymm0, %ymm1); vbroadcasti128 (8 * 16)(%rdi), %ymm4; VAESENC2(%ymm4, %ymm0, %ymm1); vbroadcasti128 (9 * 16)(%rdi), %ymm4; VAESENC2(%ymm4, %ymm0, %ymm1); vbroadcasti128 (10 * 16)(%rdi), %ymm4; cmpl $12, %r9d; jb .Lctr_enc_blk4_last; VAESENC2(%ymm4, %ymm0, %ymm1); vbroadcasti128 (11 * 16)(%rdi), %ymm4; VAESENC2(%ymm4, %ymm0, %ymm1); vbroadcasti128 (12 * 16)(%rdi), %ymm4; jz .Lctr_enc_blk4_last; VAESENC2(%ymm4, %ymm0, %ymm1); vbroadcasti128 (13 * 16)(%rdi), %ymm4; VAESENC2(%ymm4, %ymm0, %ymm1); vbroadcasti128 (14 * 16)(%rdi), %ymm4; /* Last round and output handling. */ .Lctr_enc_blk4_last: vpxor (0 * 16)(%rcx), %ymm4, %ymm5; /* Xor src to last round key. */ vpxor (2 * 16)(%rcx), %ymm4, %ymm6; leaq (4 * 16)(%rcx), %rcx; vaesenclast %ymm5, %ymm0, %ymm0; vaesenclast %ymm6, %ymm1, %ymm1; vmovdqu %ymm0, (0 * 16)(%rdx); vmovdqu %ymm1, (2 * 16)(%rdx); leaq (4 * 16)(%rdx), %rdx; jmp .Lctr_enc_blk1; .align 8 .Lctr_enc_blk4_handle_carry: /* Increment counters (handle carry). */ vpshufb %xmm13, %xmm3, %xmm1; /* be => le */ vmovdqa %xmm1, %xmm0; inc_le128(%xmm1, %xmm15, %xmm5); vinserti128 $1, %xmm1, %ymm0, %ymm3; /* ctr: +1:+0 */ vpshufb %ymm13, %ymm3, %ymm0; addq $4, %r10; adcq $0, %r11; bswapq %r10; bswapq %r11; movq %r10, 8(%rsi); movq %r11, 0(%rsi); bswapq %r10; bswapq %r11; add2_le128(%ymm3, %ymm15, %ymm14, %ymm5, %ymm6); /* ctr: +3:+2 */ vpshufb %ymm13, %ymm3, %ymm1; jmp .Lctr_enc_blk4_rounds; /* Process trailing one to three blocks, one per loop. */ .align 8 .Lctr_enc_blk1: cmpq $1, %r8; jb .Ldone_ctr_enc; leaq -1(%r8), %r8; /* Load and increament counter. */ vmovdqu (%rsi), %xmm0; addq $1, %r10; adcq $0, %r11; bswapq %r10; bswapq %r11; movq %r10, 8(%rsi); movq %r11, 0(%rsi); bswapq %r10; bswapq %r11; /* AES rounds. */ vpxor (0 * 16)(%rdi), %xmm0, %xmm0; vaesenc (1 * 16)(%rdi), %xmm0, %xmm0; vaesenc (2 * 16)(%rdi), %xmm0, %xmm0; vaesenc (3 * 16)(%rdi), %xmm0, %xmm0; vaesenc (4 * 16)(%rdi), %xmm0, %xmm0; vaesenc (5 * 16)(%rdi), %xmm0, %xmm0; vaesenc (6 * 16)(%rdi), %xmm0, %xmm0; vaesenc (7 * 16)(%rdi), %xmm0, %xmm0; vaesenc (8 * 16)(%rdi), %xmm0, %xmm0; vaesenc (9 * 16)(%rdi), %xmm0, %xmm0; vmovdqa (10 * 16)(%rdi), %xmm1; cmpl $12, %r9d; jb .Lctr_enc_blk1_last; vaesenc %xmm1, %xmm0, %xmm0; vaesenc (11 * 16)(%rdi), %xmm0, %xmm0; vmovdqa (12 * 16)(%rdi), %xmm1; jz .Lctr_enc_blk1_last; vaesenc %xmm1, %xmm0, %xmm0; vaesenc (13 * 16)(%rdi), %xmm0, %xmm0; vmovdqa (14 * 16)(%rdi), %xmm1; /* Last round and output handling. */ .Lctr_enc_blk1_last: vpxor (%rcx), %xmm1, %xmm1; /* Xor src to last round key. */ leaq 16(%rcx), %rcx; vaesenclast %xmm1, %xmm0, %xmm0; /* Last round and xor with xmm1. */ vmovdqu %xmm0, (%rdx); leaq 16(%rdx), %rdx; jmp .Lctr_enc_blk1; .align 8 .Ldone_ctr_enc: vzeroall; xorl %r10d, %r10d; xorl %r11d, %r11d; ret CFI_ENDPROC(); ELF(.size _gcry_vaes_avx2_ctr_enc_amd64,.-_gcry_vaes_avx2_ctr_enc_amd64) +/********************************************************************** + Little-endian 32-bit CTR-mode encryption (GCM-SIV) + **********************************************************************/ +ELF(.type _gcry_vaes_avx2_ctr32le_enc_amd64,@function) +.globl _gcry_vaes_avx2_ctr32le_enc_amd64 +_gcry_vaes_avx2_ctr32le_enc_amd64: + /* input: + * %rdi: round keys + * %rsi: counter + * %rdx: dst + * %rcx: src + * %r8: nblocks + * %r9: nrounds + */ + CFI_STARTPROC(); + + vbroadcasti128 (%rsi), %ymm15; // CTR + + /* Process 16 blocks per loop. */ +.align 8 +.Lctr32le_enc_blk16: + cmpq $16, %r8; + jb .Lctr32le_enc_blk8; + + leaq -16(%r8), %r8; + + vbroadcasti128 (0 * 16)(%rdi), %ymm8; + + /* Increment counters. */ + vpaddd .Lle_addd_0 rRIP, %ymm15, %ymm0; + vpaddd .Lle_addd_2 rRIP, %ymm15, %ymm1; + vpaddd .Lle_addd_4 rRIP, %ymm15, %ymm2; + vpaddd .Lle_addd_6 rRIP, %ymm15, %ymm3; + vpaddd .Lle_addd_8 rRIP, %ymm15, %ymm4; + vpaddd .Lle_addd_10 rRIP, %ymm15, %ymm5; + vpaddd .Lle_addd_12 rRIP, %ymm15, %ymm6; + vpaddd .Lle_addd_14 rRIP, %ymm15, %ymm7; + + vpaddd .Lle_addd_16_2 rRIP, %ymm15, %ymm15; + + /* AES rounds */ + XOR8(%ymm8, %ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7); + vbroadcasti128 (1 * 16)(%rdi), %ymm8; + VAESENC8(%ymm8, %ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7); + vbroadcasti128 (2 * 16)(%rdi), %ymm8; + VAESENC8(%ymm8, %ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7); + vbroadcasti128 (3 * 16)(%rdi), %ymm8; + VAESENC8(%ymm8, %ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7); + vbroadcasti128 (4 * 16)(%rdi), %ymm8; + VAESENC8(%ymm8, %ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7); + vbroadcasti128 (5 * 16)(%rdi), %ymm8; + VAESENC8(%ymm8, %ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7); + vbroadcasti128 (6 * 16)(%rdi), %ymm8; + VAESENC8(%ymm8, %ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7); + vbroadcasti128 (7 * 16)(%rdi), %ymm8; + VAESENC8(%ymm8, %ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7); + vbroadcasti128 (8 * 16)(%rdi), %ymm8; + VAESENC8(%ymm8, %ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7); + vbroadcasti128 (9 * 16)(%rdi), %ymm8; + VAESENC8(%ymm8, %ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7); + vbroadcasti128 (10 * 16)(%rdi), %ymm8; + cmpl $12, %r9d; + jb .Lctr32le_enc_blk16_last; + VAESENC8(%ymm8, %ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7); + vbroadcasti128 (11 * 16)(%rdi), %ymm8; + VAESENC8(%ymm8, %ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7); + vbroadcasti128 (12 * 16)(%rdi), %ymm8; + jz .Lctr32le_enc_blk16_last; + VAESENC8(%ymm8, %ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7); + vbroadcasti128 (13 * 16)(%rdi), %ymm8; + VAESENC8(%ymm8, %ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7); + vbroadcasti128 (14 * 16)(%rdi), %ymm8; + + /* Last round and output handling. */ + .Lctr32le_enc_blk16_last: + vpxor (0 * 16)(%rcx), %ymm8, %ymm9; /* Xor src to last round key. */ + vpxor (2 * 16)(%rcx), %ymm8, %ymm10; + vpxor (4 * 16)(%rcx), %ymm8, %ymm11; + vpxor (6 * 16)(%rcx), %ymm8, %ymm12; + vaesenclast %ymm9, %ymm0, %ymm0; + vaesenclast %ymm10, %ymm1, %ymm1; + vaesenclast %ymm11, %ymm2, %ymm2; + vaesenclast %ymm12, %ymm3, %ymm3; + vpxor (8 * 16)(%rcx), %ymm8, %ymm9; + vpxor (10 * 16)(%rcx), %ymm8, %ymm10; + vpxor (12 * 16)(%rcx), %ymm8, %ymm11; + vpxor (14 * 16)(%rcx), %ymm8, %ymm8; + leaq (16 * 16)(%rcx), %rcx; + vaesenclast %ymm9, %ymm4, %ymm4; + vaesenclast %ymm10, %ymm5, %ymm5; + vaesenclast %ymm11, %ymm6, %ymm6; + vaesenclast %ymm8, %ymm7, %ymm7; + vmovdqu %ymm0, (0 * 16)(%rdx); + vmovdqu %ymm1, (2 * 16)(%rdx); + vmovdqu %ymm2, (4 * 16)(%rdx); + vmovdqu %ymm3, (6 * 16)(%rdx); + vmovdqu %ymm4, (8 * 16)(%rdx); + vmovdqu %ymm5, (10 * 16)(%rdx); + vmovdqu %ymm6, (12 * 16)(%rdx); + vmovdqu %ymm7, (14 * 16)(%rdx); + leaq (16 * 16)(%rdx), %rdx; + + jmp .Lctr32le_enc_blk16; + + /* Handle trailing eight blocks. */ +.align 8 +.Lctr32le_enc_blk8: + cmpq $8, %r8; + jb .Lctr32le_enc_blk4; + + leaq -8(%r8), %r8; + + vbroadcasti128 (0 * 16)(%rdi), %ymm4; + + /* Increment counters. */ + vpaddd .Lle_addd_0 rRIP, %ymm15, %ymm0; + vpaddd .Lle_addd_2 rRIP, %ymm15, %ymm1; + vpaddd .Lle_addd_4 rRIP, %ymm15, %ymm2; + vpaddd .Lle_addd_6 rRIP, %ymm15, %ymm3; + + vpaddd .Lle_addd_8_2 rRIP, %ymm15, %ymm15; + + /* AES rounds */ + XOR4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3); + vbroadcasti128 (1 * 16)(%rdi), %ymm4; + VAESENC4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3); + vbroadcasti128 (2 * 16)(%rdi), %ymm4; + VAESENC4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3); + vbroadcasti128 (3 * 16)(%rdi), %ymm4; + VAESENC4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3); + vbroadcasti128 (4 * 16)(%rdi), %ymm4; + VAESENC4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3); + vbroadcasti128 (5 * 16)(%rdi), %ymm4; + VAESENC4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3); + vbroadcasti128 (6 * 16)(%rdi), %ymm4; + VAESENC4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3); + vbroadcasti128 (7 * 16)(%rdi), %ymm4; + VAESENC4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3); + vbroadcasti128 (8 * 16)(%rdi), %ymm4; + VAESENC4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3); + vbroadcasti128 (9 * 16)(%rdi), %ymm4; + VAESENC4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3); + vbroadcasti128 (10 * 16)(%rdi), %ymm4; + cmpl $12, %r9d; + jb .Lctr32le_enc_blk8_last; + VAESENC4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3); + vbroadcasti128 (11 * 16)(%rdi), %ymm4; + VAESENC4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3); + vbroadcasti128 (12 * 16)(%rdi), %ymm4; + jz .Lctr32le_enc_blk8_last; + VAESENC4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3); + vbroadcasti128 (13 * 16)(%rdi), %ymm4; + VAESENC4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3); + vbroadcasti128 (14 * 16)(%rdi), %ymm4; + + /* Last round and output handling. */ + .Lctr32le_enc_blk8_last: + vpxor (0 * 16)(%rcx), %ymm4, %ymm5; /* Xor src to last round key. */ + vpxor (2 * 16)(%rcx), %ymm4, %ymm6; + vpxor (4 * 16)(%rcx), %ymm4, %ymm7; + vpxor (6 * 16)(%rcx), %ymm4, %ymm4; + leaq (8 * 16)(%rcx), %rcx; + vaesenclast %ymm5, %ymm0, %ymm0; + vaesenclast %ymm6, %ymm1, %ymm1; + vaesenclast %ymm7, %ymm2, %ymm2; + vaesenclast %ymm4, %ymm3, %ymm3; + vmovdqu %ymm0, (0 * 16)(%rdx); + vmovdqu %ymm1, (2 * 16)(%rdx); + vmovdqu %ymm2, (4 * 16)(%rdx); + vmovdqu %ymm3, (6 * 16)(%rdx); + leaq (8 * 16)(%rdx), %rdx; + + /* Handle trailing four blocks. */ +.align 8 +.Lctr32le_enc_blk4: + cmpq $4, %r8; + jb .Lctr32le_enc_blk1; + + leaq -4(%r8), %r8; + + vbroadcasti128 (0 * 16)(%rdi), %ymm4; + + /* Increment counters. */ + vpaddd .Lle_addd_0 rRIP, %ymm15, %ymm0; + vpaddd .Lle_addd_2 rRIP, %ymm15, %ymm1; + + vpaddd .Lle_addd_4_2 rRIP, %ymm15, %ymm15; + + /* AES rounds */ + XOR2(%ymm4, %ymm0, %ymm1); + vbroadcasti128 (1 * 16)(%rdi), %ymm4; + VAESENC2(%ymm4, %ymm0, %ymm1); + vbroadcasti128 (2 * 16)(%rdi), %ymm4; + VAESENC2(%ymm4, %ymm0, %ymm1); + vbroadcasti128 (3 * 16)(%rdi), %ymm4; + VAESENC2(%ymm4, %ymm0, %ymm1); + vbroadcasti128 (4 * 16)(%rdi), %ymm4; + VAESENC2(%ymm4, %ymm0, %ymm1); + vbroadcasti128 (5 * 16)(%rdi), %ymm4; + VAESENC2(%ymm4, %ymm0, %ymm1); + vbroadcasti128 (6 * 16)(%rdi), %ymm4; + VAESENC2(%ymm4, %ymm0, %ymm1); + vbroadcasti128 (7 * 16)(%rdi), %ymm4; + VAESENC2(%ymm4, %ymm0, %ymm1); + vbroadcasti128 (8 * 16)(%rdi), %ymm4; + VAESENC2(%ymm4, %ymm0, %ymm1); + vbroadcasti128 (9 * 16)(%rdi), %ymm4; + VAESENC2(%ymm4, %ymm0, %ymm1); + vbroadcasti128 (10 * 16)(%rdi), %ymm4; + cmpl $12, %r9d; + jb .Lctr32le_enc_blk4_last; + VAESENC2(%ymm4, %ymm0, %ymm1); + vbroadcasti128 (11 * 16)(%rdi), %ymm4; + VAESENC2(%ymm4, %ymm0, %ymm1); + vbroadcasti128 (12 * 16)(%rdi), %ymm4; + jz .Lctr32le_enc_blk4_last; + VAESENC2(%ymm4, %ymm0, %ymm1); + vbroadcasti128 (13 * 16)(%rdi), %ymm4; + VAESENC2(%ymm4, %ymm0, %ymm1); + vbroadcasti128 (14 * 16)(%rdi), %ymm4; + + /* Last round and output handling. */ + .Lctr32le_enc_blk4_last: + vpxor (0 * 16)(%rcx), %ymm4, %ymm5; /* Xor src to last round key. */ + vpxor (2 * 16)(%rcx), %ymm4, %ymm6; + leaq (4 * 16)(%rcx), %rcx; + vaesenclast %ymm5, %ymm0, %ymm0; + vaesenclast %ymm6, %ymm1, %ymm1; + vmovdqu %ymm0, (0 * 16)(%rdx); + vmovdqu %ymm1, (2 * 16)(%rdx); + leaq (4 * 16)(%rdx), %rdx; + + /* Process trailing one to three blocks, one per loop. */ +.align 8 +.Lctr32le_enc_blk1: + cmpq $1, %r8; + jb .Ldone_ctr32le_enc; + + leaq -1(%r8), %r8; + + /* Load and increament counter. */ + vmovdqu %xmm15, %xmm0; + vpaddd .Lle_addd_1 rRIP, %xmm15, %xmm15; + + /* AES rounds. */ + vpxor (0 * 16)(%rdi), %xmm0, %xmm0; + vaesenc (1 * 16)(%rdi), %xmm0, %xmm0; + vaesenc (2 * 16)(%rdi), %xmm0, %xmm0; + vaesenc (3 * 16)(%rdi), %xmm0, %xmm0; + vaesenc (4 * 16)(%rdi), %xmm0, %xmm0; + vaesenc (5 * 16)(%rdi), %xmm0, %xmm0; + vaesenc (6 * 16)(%rdi), %xmm0, %xmm0; + vaesenc (7 * 16)(%rdi), %xmm0, %xmm0; + vaesenc (8 * 16)(%rdi), %xmm0, %xmm0; + vaesenc (9 * 16)(%rdi), %xmm0, %xmm0; + vmovdqa (10 * 16)(%rdi), %xmm1; + cmpl $12, %r9d; + jb .Lctr32le_enc_blk1_last; + vaesenc %xmm1, %xmm0, %xmm0; + vaesenc (11 * 16)(%rdi), %xmm0, %xmm0; + vmovdqa (12 * 16)(%rdi), %xmm1; + jz .Lctr32le_enc_blk1_last; + vaesenc %xmm1, %xmm0, %xmm0; + vaesenc (13 * 16)(%rdi), %xmm0, %xmm0; + vmovdqa (14 * 16)(%rdi), %xmm1; + + /* Last round and output handling. */ + .Lctr32le_enc_blk1_last: + vpxor (%rcx), %xmm1, %xmm1; /* Xor src to last round key. */ + leaq 16(%rcx), %rcx; + vaesenclast %xmm1, %xmm0, %xmm0; /* Last round and xor with xmm1. */ + vmovdqu %xmm0, (%rdx); + leaq 16(%rdx), %rdx; + + jmp .Lctr32le_enc_blk1; + +.align 8 +.Ldone_ctr32le_enc: + vmovdqu %xmm15, (%rsi); + vzeroall; + ret + CFI_ENDPROC(); +ELF(.size _gcry_vaes_avx2_ctr32le_enc_amd64,.-_gcry_vaes_avx2_ctr32le_enc_amd64) + /********************************************************************** OCB-mode encryption/decryption **********************************************************************/ ELF(.type _gcry_vaes_avx2_ocb_checksum,@function) _gcry_vaes_avx2_ocb_checksum: /* input: * %rax: offset pointer * %r10: plaintext pointer * %r11: nblocks */ CFI_STARTPROC(); vpxor %xmm0, %xmm0, %xmm0; cmpq $4, %r11; jb .Locb_checksum_blk1; vpxor %xmm1, %xmm1, %xmm1; vpxor %xmm2, %xmm2, %xmm2; vpxor %xmm3, %xmm3, %xmm3; cmpq $16, %r11; jb .Locb_checksum_blk4; vpxor %xmm4, %xmm4, %xmm4; vpxor %xmm5, %xmm5, %xmm5; vpxor %xmm6, %xmm6, %xmm6; vpxor %xmm7, %xmm7, %xmm7; cmpq $32, %r11; jb .Locb_checksum_blk16; vpxor %xmm8, %xmm8, %xmm8; vpxor %xmm9, %xmm9, %xmm9; vpxor %xmm10, %xmm10, %xmm10; vpxor %xmm11, %xmm11, %xmm11; vpxor %xmm12, %xmm12, %xmm12; vpxor %xmm13, %xmm13, %xmm13; vpxor %xmm14, %xmm14, %xmm14; vpxor %xmm15, %xmm15, %xmm15; .align 8 .Locb_checksum_blk32: cmpq $32, %r11; jb .Locb_checksum_blk32_done; leaq -32(%r11), %r11; vpxor (0 * 16)(%r10), %ymm0, %ymm0; vpxor (2 * 16)(%r10), %ymm1, %ymm1; vpxor (4 * 16)(%r10), %ymm2, %ymm2; vpxor (6 * 16)(%r10), %ymm3, %ymm3; vpxor (8 * 16)(%r10), %ymm4, %ymm4; vpxor (10 * 16)(%r10), %ymm5, %ymm5; vpxor (12 * 16)(%r10), %ymm6, %ymm6; vpxor (14 * 16)(%r10), %ymm7, %ymm7; vpxor (16 * 16)(%r10), %ymm8, %ymm8; vpxor (18 * 16)(%r10), %ymm9, %ymm9; vpxor (20 * 16)(%r10), %ymm10, %ymm10; vpxor (22 * 16)(%r10), %ymm11, %ymm11; vpxor (24 * 16)(%r10), %ymm12, %ymm12; vpxor (26 * 16)(%r10), %ymm13, %ymm13; vpxor (28 * 16)(%r10), %ymm14, %ymm14; vpxor (30 * 16)(%r10), %ymm15, %ymm15; leaq (32 * 16)(%r10), %r10; jmp .Locb_checksum_blk32; .align 8 .Locb_checksum_blk32_done: vpxor %ymm8, %ymm0, %ymm0; vpxor %ymm9, %ymm1, %ymm1; vpxor %ymm10, %ymm2, %ymm2; vpxor %ymm11, %ymm3, %ymm3; vpxor %ymm12, %ymm4, %ymm4; vpxor %ymm13, %ymm5, %ymm5; vpxor %ymm14, %ymm6, %ymm6; vpxor %ymm15, %ymm7, %ymm7; .align 8 .Locb_checksum_blk16: cmpq $16, %r11; jb .Locb_checksum_blk16_done; leaq -16(%r11), %r11; vpxor (0 * 16)(%r10), %ymm0, %ymm0; vpxor (2 * 16)(%r10), %ymm1, %ymm1; vpxor (4 * 16)(%r10), %ymm2, %ymm2; vpxor (6 * 16)(%r10), %ymm3, %ymm3; vpxor (8 * 16)(%r10), %ymm4, %ymm4; vpxor (10 * 16)(%r10), %ymm5, %ymm5; vpxor (12 * 16)(%r10), %ymm6, %ymm6; vpxor (14 * 16)(%r10), %ymm7, %ymm7; leaq (16 * 16)(%r10), %r10; jmp .Locb_checksum_blk16; .align 8 .Locb_checksum_blk16_done: vpxor %ymm4, %ymm0, %ymm0; vpxor %ymm5, %ymm1, %ymm1; vpxor %ymm6, %ymm2, %ymm2; vpxor %ymm7, %ymm3, %ymm3; vextracti128 $1, %ymm0, %xmm4; vextracti128 $1, %ymm1, %xmm5; vextracti128 $1, %ymm2, %xmm6; vextracti128 $1, %ymm3, %xmm7; vpxor %xmm4, %xmm0, %xmm0; vpxor %xmm5, %xmm1, %xmm1; vpxor %xmm6, %xmm2, %xmm2; vpxor %xmm7, %xmm3, %xmm3; .align 8 .Locb_checksum_blk4: cmpq $4, %r11; jb .Locb_checksum_blk4_done; leaq -4(%r11), %r11; vpxor (0 * 16)(%r10), %xmm0, %xmm0; vpxor (1 * 16)(%r10), %xmm1, %xmm1; vpxor (2 * 16)(%r10), %xmm2, %xmm2; vpxor (3 * 16)(%r10), %xmm3, %xmm3; leaq (4 * 16)(%r10), %r10; jmp .Locb_checksum_blk4; .align 8 .Locb_checksum_blk4_done: vpxor %xmm1, %xmm0, %xmm0; vpxor %xmm3, %xmm2, %xmm2; vpxor %xmm2, %xmm0, %xmm0; .align 8 .Locb_checksum_blk1: cmpq $1, %r11; jb .Locb_checksum_done; leaq -1(%r11), %r11; vpxor (%r10), %xmm0, %xmm0; leaq 16(%r10), %r10; jmp .Locb_checksum_blk1; .align 8 .Locb_checksum_done: vpxor (%rax), %xmm0, %xmm0; vmovdqu %xmm0, (%rax); ret; CFI_ENDPROC(); ELF(.size _gcry_vaes_avx2_ocb_checksum,.-_gcry_vaes_avx2_ocb_checksum) ELF(.type _gcry_vaes_avx2_ocb_crypt_amd64,@function) .globl _gcry_vaes_avx2_ocb_crypt_amd64 _gcry_vaes_avx2_ocb_crypt_amd64: /* input: * %rdi: round keys * %esi: nblk * %rdx: dst * %rcx: src * %r8: nblocks * %r9: nrounds * 16(%rbp): offset * 24(%rbp): checksum * 32(%rbp): L-array * 40(%rbp): encrypt (%r15d) */ CFI_STARTPROC(); #define STACK_REGS_POS (16 * 16 + 4 * 16) #define STACK_ALLOC (STACK_REGS_POS + 6 * 8) pushq %rbp; CFI_PUSH(%rbp); movq %rsp, %rbp; CFI_DEF_CFA_REGISTER(%rbp); subq $STACK_ALLOC, %rsp; andq $~63, %rsp; movq %r12, (STACK_REGS_POS + 0 * 8)(%rsp); CFI_REG_ON_STACK(r12, STACK_REGS_POS + 0 * 8); movq %r13, (STACK_REGS_POS + 1 * 8)(%rsp); CFI_REG_ON_STACK(r13, STACK_REGS_POS + 1 * 8); movq %r14, (STACK_REGS_POS + 2 * 8)(%rsp); CFI_REG_ON_STACK(r14, STACK_REGS_POS + 2 * 8); movq %r15, (STACK_REGS_POS + 3 * 8)(%rsp); CFI_REG_ON_STACK(r15, STACK_REGS_POS + 3 * 8); movl 40(%rbp), %r15d; /* encrypt-flag. */ movq 16(%rbp), %r14; /* offset ptr. */ /* Handle encryption checksumming. */ testl %r15d, %r15d; jz .Locb_dec_checksum_prepare; movq 24(%rbp), %rax; /* checksum ptr. */ movq %rcx, %r10; movq %r8, %r11; call _gcry_vaes_avx2_ocb_checksum; jmp .Locb_enc_checksum_done; .Locb_dec_checksum_prepare: /* Store plaintext address and number of blocks for decryption * checksumming. */ movq %rdx, (STACK_REGS_POS + 4 * 8)(%rsp); movq %r8, (STACK_REGS_POS + 5 * 8)(%rsp); .Locb_enc_checksum_done: vmovdqu (%r14), %xmm15; /* Load offset. */ movq 32(%rbp), %r14; /* L-array ptr. */ vmovdqa (0 * 16)(%rdi), %xmm0; /* first key */ movl $(10 * 16), %eax; cmpl $12, %r9d; jb .Llast_key_ptr; movl $(12 * 16), %eax; je .Llast_key_ptr; movl $(14 * 16), %eax; .align 8 .Llast_key_ptr: vpxor (%rdi, %rax), %xmm0, %xmm0; /* first key ^ last key */ vpxor (0 * 16)(%rdi), %xmm15, %xmm15; /* offset ^ first key */ vmovdqa %xmm0, (14 * 16)(%rsp); vmovdqa %xmm0, (15 * 16)(%rsp); .align 8 .Lhandle_unaligned_ocb: /* Get number of blocks to align nblk to 16 (and L-array optimization). */ movl %esi, %r10d; negl %r10d; andl $15, %r10d; cmpq %r8, %r10; cmovaq %r8, %r10; cmpq $1, %r10; jb .Lunaligned_ocb_done; /* Number of blocks after alignment. */ movq %r8, %r11; subq %r10, %r11; /* If number after alignment is less than 16, skip aligned handling * completely. */ cmp $16, %r11; cmovbq %r8, %r10; /* Unaligned: Process eight blocks per loop. */ .align 8 .Locb_unaligned_blk8: cmpq $8, %r10; jb .Locb_unaligned_blk4; leaq -8(%r8), %r8; leaq -8(%r10), %r10; leal 1(%esi), %r11d; leal 2(%esi), %r12d; leal 3(%esi), %r13d; leal 4(%esi), %eax; tzcntl %r11d, %r11d; tzcntl %r12d, %r12d; tzcntl %r13d, %r13d; tzcntl %eax, %eax; shll $4, %r11d; shll $4, %r12d; shll $4, %r13d; shll $4, %eax; vpxor (%r14, %r11), %xmm15, %xmm5; vpxor (%r14, %r12), %xmm5, %xmm6; vpxor (%r14, %r13), %xmm6, %xmm7; vpxor (%r14, %rax), %xmm7, %xmm8; leal 5(%esi), %r11d; leal 6(%esi), %r12d; leal 7(%esi), %r13d; leal 8(%esi), %esi; tzcntl %r11d, %r11d; tzcntl %r12d, %r12d; tzcntl %r13d, %r13d; tzcntl %esi, %eax; shll $4, %r11d; shll $4, %r12d; shll $4, %r13d; shll $4, %eax; vpxor (%r14, %r11), %xmm8, %xmm9; vpxor (%r14, %r12), %xmm9, %xmm10; vpxor (%r14, %r13), %xmm10, %xmm11; vpxor (%r14, %rax), %xmm11, %xmm15; vinserti128 $1, %xmm6, %ymm5, %ymm5; vinserti128 $1, %xmm8, %ymm7, %ymm6; vinserti128 $1, %xmm10, %ymm9, %ymm7; vinserti128 $1, %xmm15, %ymm11, %ymm8; vpxor (0 * 16)(%rcx), %ymm5, %ymm0; vpxor (2 * 16)(%rcx), %ymm6, %ymm1; vpxor (4 * 16)(%rcx), %ymm7, %ymm2; vpxor (6 * 16)(%rcx), %ymm8, %ymm3; leaq (8 * 16)(%rcx), %rcx; vmovdqa (14 * 16)(%rsp), %ymm9; testl %r15d, %r15d; jz .Locb_unaligned_blk8_dec; /* AES rounds */ vbroadcasti128 (1 * 16)(%rdi), %ymm4; VAESENC4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3); vbroadcasti128 (2 * 16)(%rdi), %ymm4; VAESENC4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3); vbroadcasti128 (3 * 16)(%rdi), %ymm4; VAESENC4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3); vbroadcasti128 (4 * 16)(%rdi), %ymm4; VAESENC4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3); vbroadcasti128 (5 * 16)(%rdi), %ymm4; VAESENC4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3); vbroadcasti128 (6 * 16)(%rdi), %ymm4; VAESENC4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3); vbroadcasti128 (7 * 16)(%rdi), %ymm4; VAESENC4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3); vbroadcasti128 (8 * 16)(%rdi), %ymm4; VAESENC4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3); vbroadcasti128 (9 * 16)(%rdi), %ymm4; VAESENC4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3); cmpl $12, %r9d; jb .Locb_unaligned_blk8_enc_last; vbroadcasti128 (10 * 16)(%rdi), %ymm4; VAESENC4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3); vbroadcasti128 (11 * 16)(%rdi), %ymm4; VAESENC4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3); jz .Locb_unaligned_blk8_enc_last; vbroadcasti128 (12 * 16)(%rdi), %ymm4; VAESENC4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3); vbroadcasti128 (13 * 16)(%rdi), %ymm4; VAESENC4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3); /* Last round and output handling. */ .Locb_unaligned_blk8_enc_last: vpxor %ymm5, %ymm9, %ymm5; /* Xor src to last round key. */ vpxor %ymm6, %ymm9, %ymm6; vpxor %ymm7, %ymm9, %ymm7; vpxor %ymm8, %ymm9, %ymm4; vaesenclast %ymm5, %ymm0, %ymm0; vaesenclast %ymm6, %ymm1, %ymm1; vaesenclast %ymm7, %ymm2, %ymm2; vaesenclast %ymm4, %ymm3, %ymm3; vmovdqu %ymm0, (0 * 16)(%rdx); vmovdqu %ymm1, (2 * 16)(%rdx); vmovdqu %ymm2, (4 * 16)(%rdx); vmovdqu %ymm3, (6 * 16)(%rdx); leaq (8 * 16)(%rdx), %rdx; jmp .Locb_unaligned_blk8; .align 8 .Locb_unaligned_blk8_dec: /* AES rounds */ vbroadcasti128 (1 * 16)(%rdi), %ymm4; VAESDEC4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3); vbroadcasti128 (2 * 16)(%rdi), %ymm4; VAESDEC4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3); vbroadcasti128 (3 * 16)(%rdi), %ymm4; VAESDEC4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3); vbroadcasti128 (4 * 16)(%rdi), %ymm4; VAESDEC4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3); vbroadcasti128 (5 * 16)(%rdi), %ymm4; VAESDEC4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3); vbroadcasti128 (6 * 16)(%rdi), %ymm4; VAESDEC4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3); vbroadcasti128 (7 * 16)(%rdi), %ymm4; VAESDEC4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3); vbroadcasti128 (8 * 16)(%rdi), %ymm4; VAESDEC4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3); vbroadcasti128 (9 * 16)(%rdi), %ymm4; VAESDEC4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3); cmpl $12, %r9d; jb .Locb_unaligned_blk8_dec_last; vbroadcasti128 (10 * 16)(%rdi), %ymm4; VAESDEC4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3); vbroadcasti128 (11 * 16)(%rdi), %ymm4; VAESDEC4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3); jz .Locb_unaligned_blk8_dec_last; vbroadcasti128 (12 * 16)(%rdi), %ymm4; VAESDEC4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3); vbroadcasti128 (13 * 16)(%rdi), %ymm4; VAESDEC4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3); /* Last round and output handling. */ .Locb_unaligned_blk8_dec_last: vpxor %ymm5, %ymm9, %ymm5; /* Xor src to last round key. */ vpxor %ymm6, %ymm9, %ymm6; vpxor %ymm7, %ymm9, %ymm7; vpxor %ymm8, %ymm9, %ymm4; vaesdeclast %ymm5, %ymm0, %ymm0; vaesdeclast %ymm6, %ymm1, %ymm1; vaesdeclast %ymm7, %ymm2, %ymm2; vaesdeclast %ymm4, %ymm3, %ymm3; vmovdqu %ymm0, (0 * 16)(%rdx); vmovdqu %ymm1, (2 * 16)(%rdx); vmovdqu %ymm2, (4 * 16)(%rdx); vmovdqu %ymm3, (6 * 16)(%rdx); leaq (8 * 16)(%rdx), %rdx; jmp .Locb_unaligned_blk8; /* Unaligned: Process four blocks. */ .align 8 .Locb_unaligned_blk4: cmpq $4, %r10; jb .Locb_unaligned_blk1; leaq -4(%r8), %r8; leaq -4(%r10), %r10; leal 1(%esi), %r11d; leal 2(%esi), %r12d; leal 3(%esi), %r13d; leal 4(%esi), %esi; tzcntl %r11d, %r11d; tzcntl %r12d, %r12d; tzcntl %r13d, %r13d; tzcntl %esi, %eax; shll $4, %r11d; shll $4, %r12d; shll $4, %r13d; shll $4, %eax; vpxor (%r14, %r11), %xmm15, %xmm5; vpxor (%r14, %r12), %xmm5, %xmm6; vinserti128 $1, %xmm6, %ymm5, %ymm5; vpxor (%r14, %r13), %xmm6, %xmm7; vpxor (%r14, %rax), %xmm7, %xmm15; vinserti128 $1, %xmm15, %ymm7, %ymm6; vpxor (0 * 16)(%rcx), %ymm5, %ymm0; vpxor (2 * 16)(%rcx), %ymm6, %ymm1; leaq (4 * 16)(%rcx), %rcx; testl %r15d, %r15d; jz .Locb_unaligned_blk4_dec; /* AES rounds */ vbroadcasti128 (1 * 16)(%rdi), %ymm4; VAESENC2(%ymm4, %ymm0, %ymm1); vbroadcasti128 (2 * 16)(%rdi), %ymm4; VAESENC2(%ymm4, %ymm0, %ymm1); vbroadcasti128 (3 * 16)(%rdi), %ymm4; VAESENC2(%ymm4, %ymm0, %ymm1); vbroadcasti128 (4 * 16)(%rdi), %ymm4; VAESENC2(%ymm4, %ymm0, %ymm1); vbroadcasti128 (5 * 16)(%rdi), %ymm4; VAESENC2(%ymm4, %ymm0, %ymm1); vbroadcasti128 (6 * 16)(%rdi), %ymm4; VAESENC2(%ymm4, %ymm0, %ymm1); vbroadcasti128 (7 * 16)(%rdi), %ymm4; VAESENC2(%ymm4, %ymm0, %ymm1); vbroadcasti128 (8 * 16)(%rdi), %ymm4; VAESENC2(%ymm4, %ymm0, %ymm1); vbroadcasti128 (9 * 16)(%rdi), %ymm4; VAESENC2(%ymm4, %ymm0, %ymm1); cmpl $12, %r9d; jb .Locb_unaligned_blk4_enc_last; vbroadcasti128 (10 * 16)(%rdi), %ymm4; VAESENC2(%ymm4, %ymm0, %ymm1); vbroadcasti128 (11 * 16)(%rdi), %ymm4; VAESENC2(%ymm4, %ymm0, %ymm1); jz .Locb_unaligned_blk4_enc_last; vbroadcasti128 (12 * 16)(%rdi), %ymm4; VAESENC2(%ymm4, %ymm0, %ymm1); vbroadcasti128 (13 * 16)(%rdi), %ymm4; VAESENC2(%ymm4, %ymm0, %ymm1); /* Last round and output handling. */ .Locb_unaligned_blk4_enc_last: vmovdqa (14 * 16)(%rsp), %ymm8; vpxor %ymm5, %ymm8, %ymm5; /* Xor src to last round key. */ vpxor %ymm6, %ymm8, %ymm6; vaesenclast %ymm5, %ymm0, %ymm0; vaesenclast %ymm6, %ymm1, %ymm1; vmovdqu %ymm0, (0 * 16)(%rdx); vmovdqu %ymm1, (2 * 16)(%rdx); leaq (4 * 16)(%rdx), %rdx; jmp .Locb_unaligned_blk1; .align 8 .Locb_unaligned_blk4_dec: /* AES rounds */ vbroadcasti128 (1 * 16)(%rdi), %ymm4; VAESDEC2(%ymm4, %ymm0, %ymm1); vbroadcasti128 (2 * 16)(%rdi), %ymm4; VAESDEC2(%ymm4, %ymm0, %ymm1); vbroadcasti128 (3 * 16)(%rdi), %ymm4; VAESDEC2(%ymm4, %ymm0, %ymm1); vbroadcasti128 (4 * 16)(%rdi), %ymm4; VAESDEC2(%ymm4, %ymm0, %ymm1); vbroadcasti128 (5 * 16)(%rdi), %ymm4; VAESDEC2(%ymm4, %ymm0, %ymm1); vbroadcasti128 (6 * 16)(%rdi), %ymm4; VAESDEC2(%ymm4, %ymm0, %ymm1); vbroadcasti128 (7 * 16)(%rdi), %ymm4; VAESDEC2(%ymm4, %ymm0, %ymm1); vbroadcasti128 (8 * 16)(%rdi), %ymm4; VAESDEC2(%ymm4, %ymm0, %ymm1); vbroadcasti128 (9 * 16)(%rdi), %ymm4; VAESDEC2(%ymm4, %ymm0, %ymm1); cmpl $12, %r9d; jb .Locb_unaligned_blk4_dec_last; vbroadcasti128 (10 * 16)(%rdi), %ymm4; VAESDEC2(%ymm4, %ymm0, %ymm1); vbroadcasti128 (11 * 16)(%rdi), %ymm4; VAESDEC2(%ymm4, %ymm0, %ymm1); jz .Locb_unaligned_blk4_dec_last; vbroadcasti128 (12 * 16)(%rdi), %ymm4; VAESDEC2(%ymm4, %ymm0, %ymm1); vbroadcasti128 (13 * 16)(%rdi), %ymm4; VAESDEC2(%ymm4, %ymm0, %ymm1); /* Last round and output handling. */ .Locb_unaligned_blk4_dec_last: vmovdqa (14 * 16)(%rsp), %ymm8; vpxor %ymm5, %ymm8, %ymm5; /* Xor src to last round key. */ vpxor %ymm6, %ymm8, %ymm6; vaesdeclast %ymm5, %ymm0, %ymm0; vaesdeclast %ymm6, %ymm1, %ymm1; vmovdqu %ymm0, (0 * 16)(%rdx); vmovdqu %ymm1, (2 * 16)(%rdx); leaq (4 * 16)(%rdx), %rdx; /* Unaligned: Process one block per loop. */ .align 8 .Locb_unaligned_blk1: cmpq $1, %r10; jb .Lunaligned_ocb_done; leaq -1(%r8), %r8; leaq -1(%r10), %r10; leal 1(%esi), %esi; tzcntl %esi, %r11d; shll $4, %r11d; vpxor (%r14, %r11), %xmm15, %xmm15; vpxor (%rcx), %xmm15, %xmm0; leaq 16(%rcx), %rcx; testl %r15d, %r15d; jz .Locb_unaligned_blk1_dec; /* AES rounds. */ vaesenc (1 * 16)(%rdi), %xmm0, %xmm0; vaesenc (2 * 16)(%rdi), %xmm0, %xmm0; vaesenc (3 * 16)(%rdi), %xmm0, %xmm0; vaesenc (4 * 16)(%rdi), %xmm0, %xmm0; vaesenc (5 * 16)(%rdi), %xmm0, %xmm0; vaesenc (6 * 16)(%rdi), %xmm0, %xmm0; vaesenc (7 * 16)(%rdi), %xmm0, %xmm0; vaesenc (8 * 16)(%rdi), %xmm0, %xmm0; vaesenc (9 * 16)(%rdi), %xmm0, %xmm0; cmpl $12, %r9d; jb .Locb_unaligned_blk1_enc_last; vaesenc (10 * 16)(%rdi), %xmm0, %xmm0; vaesenc (11 * 16)(%rdi), %xmm0, %xmm0; jz .Locb_unaligned_blk1_enc_last; vaesenc (12 * 16)(%rdi), %xmm0, %xmm0; vaesenc (13 * 16)(%rdi), %xmm0, %xmm0; /* Last round and output handling. */ .Locb_unaligned_blk1_enc_last: vpxor (14 * 16)(%rsp), %xmm15, %xmm1; vaesenclast %xmm1, %xmm0, %xmm0; vmovdqu %xmm0, (%rdx); leaq 16(%rdx), %rdx; jmp .Locb_unaligned_blk1; .align 8 .Locb_unaligned_blk1_dec: /* AES rounds. */ vaesdec (1 * 16)(%rdi), %xmm0, %xmm0; vaesdec (2 * 16)(%rdi), %xmm0, %xmm0; vaesdec (3 * 16)(%rdi), %xmm0, %xmm0; vaesdec (4 * 16)(%rdi), %xmm0, %xmm0; vaesdec (5 * 16)(%rdi), %xmm0, %xmm0; vaesdec (6 * 16)(%rdi), %xmm0, %xmm0; vaesdec (7 * 16)(%rdi), %xmm0, %xmm0; vaesdec (8 * 16)(%rdi), %xmm0, %xmm0; vaesdec (9 * 16)(%rdi), %xmm0, %xmm0; cmpl $12, %r9d; jb .Locb_unaligned_blk1_dec_last; vaesdec (10 * 16)(%rdi), %xmm0, %xmm0; vaesdec (11 * 16)(%rdi), %xmm0, %xmm0; jz .Locb_unaligned_blk1_dec_last; vaesdec (12 * 16)(%rdi), %xmm0, %xmm0; vaesdec (13 * 16)(%rdi), %xmm0, %xmm0; /* Last round and output handling. */ .Locb_unaligned_blk1_dec_last: vpxor (14 * 16)(%rsp), %xmm15, %xmm1; vaesdeclast %xmm1, %xmm0, %xmm0; vmovdqu %xmm0, (%rdx); leaq 16(%rdx), %rdx; jmp .Locb_unaligned_blk1; .align 8 .Lunaligned_ocb_done: cmpq $1, %r8; jb .Ldone_ocb; /* Short buffers do not benefit from L-array optimization. */ movq %r8, %r10; cmpq $16, %r8; jb .Locb_unaligned_blk8; vinserti128 $1, %xmm15, %ymm15, %ymm15; /* Prepare L-array optimization. * Since nblk is aligned to 16, offsets will have following * construction: * - block1 = ntz{0} = offset ^ L[0] * - block2 = ntz{1} = offset ^ L[0] ^ L[1] * - block3 = ntz{0} = offset ^ L[1] * - block4 = ntz{2} = offset ^ L[1] ^ L[2] * - block5 = ntz{0} = offset ^ L[0] ^ L[1] ^ L[2] * - block6 = ntz{1} = offset ^ L[0] ^ L[2] * - block7 = ntz{0} = offset ^ L[2] * - block8 = ntz{3} = offset ^ L[2] ^ L[3] * - block9 = ntz{0} = offset ^ L[0] ^ L[2] ^ L[3] * - block10 = ntz{1} = offset ^ L[0] ^ L[1] ^ L[2] ^ L[3] * - block11 = ntz{0} = offset ^ L[1] ^ L[2] ^ L[3] * - block12 = ntz{2} = offset ^ L[1] ^ L[3] * - block13 = ntz{0} = offset ^ L[0] ^ L[1] ^ L[3] * - block14 = ntz{1} = offset ^ L[0] ^ L[3] * - block15 = ntz{0} = offset ^ L[3] * - block16 = ntz{x} = offset ^ L[3] ^ L[ntz{x}] */ vmovdqu (0 * 16)(%r14), %xmm0; vmovdqu (1 * 16)(%r14), %xmm1; vmovdqu (2 * 16)(%r14), %xmm2; vmovdqu (3 * 16)(%r14), %xmm3; vpxor %xmm0, %xmm1, %xmm4; /* L[0] ^ L[1] */ vpxor %xmm0, %xmm2, %xmm5; /* L[0] ^ L[2] */ vpxor %xmm0, %xmm3, %xmm6; /* L[0] ^ L[3] */ vpxor %xmm1, %xmm2, %xmm7; /* L[1] ^ L[2] */ vpxor %xmm1, %xmm3, %xmm8; /* L[1] ^ L[3] */ vpxor %xmm2, %xmm3, %xmm9; /* L[2] ^ L[3] */ vpxor %xmm4, %xmm2, %xmm10; /* L[0] ^ L[1] ^ L[2] */ vpxor %xmm5, %xmm3, %xmm11; /* L[0] ^ L[2] ^ L[3] */ vpxor %xmm7, %xmm3, %xmm12; /* L[1] ^ L[2] ^ L[3] */ vpxor %xmm0, %xmm8, %xmm13; /* L[0] ^ L[1] ^ L[3] */ vpxor %xmm4, %xmm9, %xmm14; /* L[0] ^ L[1] ^ L[2] ^ L[3] */ vinserti128 $1, %xmm4, %ymm0, %ymm0; vinserti128 $1, %xmm7, %ymm1, %ymm1; vinserti128 $1, %xmm5, %ymm10, %ymm10; vinserti128 $1, %xmm9, %ymm2, %ymm2; vinserti128 $1, %xmm14, %ymm11, %ymm11; vinserti128 $1, %xmm8, %ymm12, %ymm12; vinserti128 $1, %xmm6, %ymm13, %ymm13; vmovdqa %ymm0, (0 * 16)(%rsp); vmovdqa %ymm1, (2 * 16)(%rsp); vmovdqa %ymm10, (4 * 16)(%rsp); vmovdqa %ymm2, (6 * 16)(%rsp); vmovdqa %ymm11, (8 * 16)(%rsp); vmovdqa %ymm12, (10 * 16)(%rsp); vmovdqa %ymm13, (12 * 16)(%rsp); /* Aligned: Process 16 blocks per loop. */ .align 8 .Locb_aligned_blk16: cmpq $16, %r8; jb .Locb_aligned_blk8; leaq -16(%r8), %r8; leal 16(%esi), %esi; tzcntl %esi, %eax; shll $4, %eax; vpxor (0 * 16)(%rsp), %ymm15, %ymm8; vpxor (2 * 16)(%rsp), %ymm15, %ymm9; vpxor (4 * 16)(%rsp), %ymm15, %ymm10; vpxor (6 * 16)(%rsp), %ymm15, %ymm11; vpxor (8 * 16)(%rsp), %ymm15, %ymm12; vpxor (3 * 16)(%r14), %xmm15, %xmm13; /* offset ^ first key ^ L[3] */ vpxor (%r14, %rax), %xmm13, %xmm14; /* offset ^ first key ^ L[3] ^ L[ntz{nblk+16}] */ vinserti128 $1, %xmm14, %ymm13, %ymm14; vpxor (10 * 16)(%rsp), %ymm15, %ymm13; vpxor (14 * 16)(%rcx), %ymm14, %ymm7; vpxor (0 * 16)(%rcx), %ymm8, %ymm0; vpxor (2 * 16)(%rcx), %ymm9, %ymm1; vpxor (4 * 16)(%rcx), %ymm10, %ymm2; vpxor (6 * 16)(%rcx), %ymm11, %ymm3; vpxor (8 * 16)(%rcx), %ymm12, %ymm4; vpxor (10 * 16)(%rcx), %ymm13, %ymm5; vmovdqa %ymm13, (16 * 16)(%rsp); vpxor (12 * 16)(%rsp), %ymm15, %ymm13; vpxor (12 * 16)(%rcx), %ymm13, %ymm6; vmovdqa %ymm13, (18 * 16)(%rsp); leaq (16 * 16)(%rcx), %rcx; vperm2i128 $0x11, %ymm14, %ymm14, %ymm15; testl %r15d, %r15d; jz .Locb_aligned_blk16_dec; /* AES rounds */ vbroadcasti128 (1 * 16)(%rdi), %ymm13; VAESENC8(%ymm13, %ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7); vbroadcasti128 (2 * 16)(%rdi), %ymm13; VAESENC8(%ymm13, %ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7); vbroadcasti128 (3 * 16)(%rdi), %ymm13; VAESENC8(%ymm13, %ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7); vbroadcasti128 (4 * 16)(%rdi), %ymm13; VAESENC8(%ymm13, %ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7); vbroadcasti128 (5 * 16)(%rdi), %ymm13; VAESENC8(%ymm13, %ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7); vbroadcasti128 (6 * 16)(%rdi), %ymm13; VAESENC8(%ymm13, %ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7); vbroadcasti128 (7 * 16)(%rdi), %ymm13; VAESENC8(%ymm13, %ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7); vbroadcasti128 (8 * 16)(%rdi), %ymm13; VAESENC8(%ymm13, %ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7); vbroadcasti128 (9 * 16)(%rdi), %ymm13; VAESENC8(%ymm13, %ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7); cmpl $12, %r9d; jb .Locb_aligned_blk16_enc_last; vbroadcasti128 (10 * 16)(%rdi), %ymm13; VAESENC8(%ymm13, %ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7); vbroadcasti128 (11 * 16)(%rdi), %ymm13; VAESENC8(%ymm13, %ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7); jz .Locb_aligned_blk16_enc_last; vbroadcasti128 (12 * 16)(%rdi), %ymm13; VAESENC8(%ymm13, %ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7); vbroadcasti128 (13 * 16)(%rdi), %ymm13; VAESENC8(%ymm13, %ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7); /* Last round and output handling. */ .Locb_aligned_blk16_enc_last: vmovdqa (14 * 16)(%rsp), %ymm13; vpxor %ymm8, %ymm13, %ymm8; vpxor %ymm9, %ymm13, %ymm9; vpxor %ymm10, %ymm13, %ymm10; vpxor %ymm11, %ymm13, %ymm11; vaesenclast %ymm8, %ymm0, %ymm0; vaesenclast %ymm9, %ymm1, %ymm1; vaesenclast %ymm10, %ymm2, %ymm2; vaesenclast %ymm11, %ymm3, %ymm3; vpxor %ymm12, %ymm13, %ymm12; vpxor (16 * 16)(%rsp), %ymm13, %ymm8; vpxor (18 * 16)(%rsp), %ymm13, %ymm9; vpxor %ymm14, %ymm13, %ymm13; vaesenclast %ymm12, %ymm4, %ymm4; vaesenclast %ymm8, %ymm5, %ymm5; vaesenclast %ymm9, %ymm6, %ymm6; vaesenclast %ymm13, %ymm7, %ymm7; vmovdqu %ymm0, (0 * 16)(%rdx); vmovdqu %ymm1, (2 * 16)(%rdx); vmovdqu %ymm2, (4 * 16)(%rdx); vmovdqu %ymm3, (6 * 16)(%rdx); vmovdqu %ymm4, (8 * 16)(%rdx); vmovdqu %ymm5, (10 * 16)(%rdx); vmovdqu %ymm6, (12 * 16)(%rdx); vmovdqu %ymm7, (14 * 16)(%rdx); leaq (16 * 16)(%rdx), %rdx; jmp .Locb_aligned_blk16; .align 8 .Locb_aligned_blk16_dec: /* AES rounds */ vbroadcasti128 (1 * 16)(%rdi), %ymm13; VAESDEC8(%ymm13, %ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7); vbroadcasti128 (2 * 16)(%rdi), %ymm13; VAESDEC8(%ymm13, %ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7); vbroadcasti128 (3 * 16)(%rdi), %ymm13; VAESDEC8(%ymm13, %ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7); vbroadcasti128 (4 * 16)(%rdi), %ymm13; VAESDEC8(%ymm13, %ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7); vbroadcasti128 (5 * 16)(%rdi), %ymm13; VAESDEC8(%ymm13, %ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7); vbroadcasti128 (6 * 16)(%rdi), %ymm13; VAESDEC8(%ymm13, %ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7); vbroadcasti128 (7 * 16)(%rdi), %ymm13; VAESDEC8(%ymm13, %ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7); vbroadcasti128 (8 * 16)(%rdi), %ymm13; VAESDEC8(%ymm13, %ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7); vbroadcasti128 (9 * 16)(%rdi), %ymm13; VAESDEC8(%ymm13, %ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7); cmpl $12, %r9d; jb .Locb_aligned_blk16_dec_last; vbroadcasti128 (10 * 16)(%rdi), %ymm13; VAESDEC8(%ymm13, %ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7); vbroadcasti128 (11 * 16)(%rdi), %ymm13; VAESDEC8(%ymm13, %ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7); jz .Locb_aligned_blk16_dec_last; vbroadcasti128 (12 * 16)(%rdi), %ymm13; VAESDEC8(%ymm13, %ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7); vbroadcasti128 (13 * 16)(%rdi), %ymm13; VAESDEC8(%ymm13, %ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7); /* Last round and output handling. */ .Locb_aligned_blk16_dec_last: vmovdqa (14 * 16)(%rsp), %ymm13; vpxor %ymm8, %ymm13, %ymm8; vpxor %ymm9, %ymm13, %ymm9; vpxor %ymm10, %ymm13, %ymm10; vpxor %ymm11, %ymm13, %ymm11; vaesdeclast %ymm8, %ymm0, %ymm0; vaesdeclast %ymm9, %ymm1, %ymm1; vaesdeclast %ymm10, %ymm2, %ymm2; vaesdeclast %ymm11, %ymm3, %ymm3; vpxor %ymm12, %ymm13, %ymm12; vpxor (16 * 16)(%rsp), %ymm13, %ymm8; vpxor (18 * 16)(%rsp), %ymm13, %ymm9; vpxor %ymm14, %ymm13, %ymm13; vaesdeclast %ymm12, %ymm4, %ymm4; vaesdeclast %ymm8, %ymm5, %ymm5; vaesdeclast %ymm9, %ymm6, %ymm6; vaesdeclast %ymm13, %ymm7, %ymm7; vmovdqu %ymm0, (0 * 16)(%rdx); vmovdqu %ymm1, (2 * 16)(%rdx); vmovdqu %ymm2, (4 * 16)(%rdx); vmovdqu %ymm3, (6 * 16)(%rdx); vmovdqu %ymm4, (8 * 16)(%rdx); vmovdqu %ymm5, (10 * 16)(%rdx); vmovdqu %ymm6, (12 * 16)(%rdx); vmovdqu %ymm7, (14 * 16)(%rdx); leaq (16 * 16)(%rdx), %rdx; jmp .Locb_aligned_blk16; /* Aligned: Process trailing eight blocks. */ .align 8 .Locb_aligned_blk8: cmpq $8, %r8; jb .Locb_aligned_done; leaq -8(%r8), %r8; leal 8(%esi), %esi; tzcntl %esi, %eax; shll $4, %eax; vpxor (0 * 16)(%rsp), %ymm15, %ymm5; vpxor (2 * 16)(%rsp), %ymm15, %ymm6; vpxor (4 * 16)(%rsp), %ymm15, %ymm7; vpxor (2 * 16)(%r14), %xmm15, %xmm13; /* offset ^ first key ^ L[2] */ vpxor (%r14, %rax), %xmm13, %xmm14; /* offset ^ first key ^ L[2] ^ L[ntz{nblk+8}] */ vinserti128 $1, %xmm14, %ymm13, %ymm14; vpxor (0 * 16)(%rcx), %ymm5, %ymm0; vpxor (2 * 16)(%rcx), %ymm6, %ymm1; vpxor (4 * 16)(%rcx), %ymm7, %ymm2; vpxor (6 * 16)(%rcx), %ymm14, %ymm3; leaq (8 * 16)(%rcx), %rcx; vperm2i128 $0x11, %ymm14, %ymm14, %ymm15; vmovdqa (14 * 16)(%rsp), %ymm8; testl %r15d, %r15d; jz .Locb_aligned_blk8_dec; /* AES rounds */ vbroadcasti128 (1 * 16)(%rdi), %ymm4; VAESENC4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3); vbroadcasti128 (2 * 16)(%rdi), %ymm4; VAESENC4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3); vbroadcasti128 (3 * 16)(%rdi), %ymm4; VAESENC4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3); vbroadcasti128 (4 * 16)(%rdi), %ymm4; VAESENC4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3); vbroadcasti128 (5 * 16)(%rdi), %ymm4; VAESENC4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3); vbroadcasti128 (6 * 16)(%rdi), %ymm4; VAESENC4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3); vbroadcasti128 (7 * 16)(%rdi), %ymm4; VAESENC4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3); vbroadcasti128 (8 * 16)(%rdi), %ymm4; VAESENC4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3); vbroadcasti128 (9 * 16)(%rdi), %ymm4; VAESENC4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3); cmpl $12, %r9d; jb .Locb_aligned_blk8_enc_last; vbroadcasti128 (10 * 16)(%rdi), %ymm4; VAESENC4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3); vbroadcasti128 (11 * 16)(%rdi), %ymm4; VAESENC4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3); jz .Locb_aligned_blk8_enc_last; vbroadcasti128 (12 * 16)(%rdi), %ymm4; VAESENC4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3); vbroadcasti128 (13 * 16)(%rdi), %ymm4; VAESENC4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3); /* Last round and output handling. */ .Locb_aligned_blk8_enc_last: vpxor %ymm5, %ymm8, %ymm5; vpxor %ymm6, %ymm8, %ymm6; vpxor %ymm7, %ymm8, %ymm7; vpxor %ymm14, %ymm8, %ymm4; vaesenclast %ymm5, %ymm0, %ymm0; vaesenclast %ymm6, %ymm1, %ymm1; vaesenclast %ymm7, %ymm2, %ymm2; vaesenclast %ymm4, %ymm3, %ymm3; vmovdqu %ymm0, (0 * 16)(%rdx); vmovdqu %ymm1, (2 * 16)(%rdx); vmovdqu %ymm2, (4 * 16)(%rdx); vmovdqu %ymm3, (6 * 16)(%rdx); leaq (8 * 16)(%rdx), %rdx; jmp .Locb_aligned_done; .align 8 .Locb_aligned_blk8_dec: /* AES rounds */ vbroadcasti128 (1 * 16)(%rdi), %ymm4; VAESDEC4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3); vbroadcasti128 (2 * 16)(%rdi), %ymm4; VAESDEC4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3); vbroadcasti128 (3 * 16)(%rdi), %ymm4; VAESDEC4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3); vbroadcasti128 (4 * 16)(%rdi), %ymm4; VAESDEC4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3); vbroadcasti128 (5 * 16)(%rdi), %ymm4; VAESDEC4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3); vbroadcasti128 (6 * 16)(%rdi), %ymm4; VAESDEC4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3); vbroadcasti128 (7 * 16)(%rdi), %ymm4; VAESDEC4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3); vbroadcasti128 (8 * 16)(%rdi), %ymm4; VAESDEC4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3); vbroadcasti128 (9 * 16)(%rdi), %ymm4; VAESDEC4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3); cmpl $12, %r9d; jb .Locb_aligned_blk8_dec_last; vbroadcasti128 (10 * 16)(%rdi), %ymm4; VAESDEC4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3); vbroadcasti128 (11 * 16)(%rdi), %ymm4; VAESDEC4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3); jz .Locb_aligned_blk8_dec_last; vbroadcasti128 (12 * 16)(%rdi), %ymm4; VAESDEC4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3); vbroadcasti128 (13 * 16)(%rdi), %ymm4; VAESDEC4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3); vbroadcasti128 (14 * 16)(%rdi), %ymm4; /* Last round and output handling. */ .Locb_aligned_blk8_dec_last: vpxor %ymm5, %ymm8, %ymm5; vpxor %ymm6, %ymm8, %ymm6; vpxor %ymm7, %ymm8, %ymm7; vpxor %ymm14, %ymm8, %ymm4; vaesdeclast %ymm5, %ymm0, %ymm0; vaesdeclast %ymm6, %ymm1, %ymm1; vaesdeclast %ymm7, %ymm2, %ymm2; vaesdeclast %ymm4, %ymm3, %ymm3; vmovdqu %ymm0, (0 * 16)(%rdx); vmovdqu %ymm1, (2 * 16)(%rdx); vmovdqu %ymm2, (4 * 16)(%rdx); vmovdqu %ymm3, (6 * 16)(%rdx); leaq (8 * 16)(%rdx), %rdx; .align 8 .Locb_aligned_done: /* Burn stack. */ vpxor %ymm0, %ymm0, %ymm0; vmovdqa %ymm0, (0 * 16)(%rsp); vmovdqa %ymm0, (2 * 16)(%rsp); vmovdqa %ymm0, (4 * 16)(%rsp); vmovdqa %ymm0, (6 * 16)(%rsp); vmovdqa %ymm0, (8 * 16)(%rsp); vmovdqa %ymm0, (10 * 16)(%rsp); vmovdqa %ymm0, (12 * 16)(%rsp); vmovdqa %ymm0, (16 * 16)(%rsp); vmovdqa %ymm0, (18 * 16)(%rsp); /* Handle tailing 1…7 blocks in nblk-unaligned loop. */ movq %r8, %r10; cmpq $1, %r8; jnb .Locb_unaligned_blk8; .align 8 .Ldone_ocb: movq 16(%rbp), %r14; /* offset ptr. */ vpxor (0 * 16)(%rdi), %xmm15, %xmm15; /* offset ^ first key ^ first key */ vmovdqu %xmm15, (%r14); /* Store offset. */ /* Handle decryption checksumming. */ testl %r15d, %r15d; jnz .Locb_dec_checksum_done; movq 24(%rbp), %rax; /* checksum ptr. */ movq (STACK_REGS_POS + 4 * 8)(%rsp), %r10; movq (STACK_REGS_POS + 5 * 8)(%rsp), %r11; call _gcry_vaes_avx2_ocb_checksum; .Locb_dec_checksum_done: /* Burn stack. */ vpxor %ymm0, %ymm0, %ymm0; vmovdqa %ymm0, (14 * 16)(%rsp); vzeroall; movq (STACK_REGS_POS + 0 * 8)(%rsp), %r12; CFI_RESTORE(%r12); movq (STACK_REGS_POS + 1 * 8)(%rsp), %r13; CFI_RESTORE(%r13); movq (STACK_REGS_POS + 2 * 8)(%rsp), %r14; CFI_RESTORE(%r14); movq (STACK_REGS_POS + 3 * 8)(%rsp), %r15; CFI_RESTORE(%r15); leave; CFI_LEAVE(); ret #undef STACK_REGS_POS #undef STACK_ALLOC CFI_ENDPROC(); ELF(.size _gcry_vaes_avx2_ocb_crypt_amd64,.-_gcry_vaes_avx2_ocb_crypt_amd64) /********************************************************************** CTR-mode encryption **********************************************************************/ ELF(.type _gcry_vaes_avx2_xts_crypt_amd64,@function) .globl _gcry_vaes_avx2_xts_crypt_amd64 _gcry_vaes_avx2_xts_crypt_amd64: /* input: * %rdi: round keys * %rsi: tweak * %rdx: dst * %rcx: src * %r8: nblocks * %r9: nrounds * 8(%rsp): encrypt */ CFI_STARTPROC(); movl 8(%rsp), %eax; #define tweak_clmul(shift, out, tweak, hi_tweak, tmp1, tmp2) \ vpsrld $(32-(shift)), hi_tweak, tmp2; \ vpsllq $(shift), tweak, out; \ vpclmulqdq $0, .Lxts_gfmul_clmul rRIP, tmp2, tmp1; \ vpunpckhqdq tmp2, tmp1, tmp1; \ vpxor tmp1, out, out; /* Prepare tweak. */ vmovdqu (%rsi), %xmm15; vpshufb .Lxts_high_bit_shuf rRIP, %xmm15, %xmm13; tweak_clmul(1, %xmm11, %xmm15, %xmm13, %xmm0, %xmm1); vinserti128 $1, %xmm11, %ymm15, %ymm15; /* tweak:tweak1 */ vpshufb .Lxts_high_bit_shuf rRIP, %ymm15, %ymm13; cmpq $8, %r8; jb .Lxts_crypt_blk4; /* Process eight blocks per loop. */ leaq -8(%r8), %r8; vmovdqa %ymm15, %ymm5; tweak_clmul(2, %ymm6, %ymm15, %ymm13, %ymm0, %ymm1); tweak_clmul(4, %ymm7, %ymm15, %ymm13, %ymm0, %ymm1); tweak_clmul(6, %ymm8, %ymm15, %ymm13, %ymm0, %ymm1); tweak_clmul(8, %ymm15, %ymm15, %ymm13, %ymm0, %ymm1); vpshufb .Lxts_high_bit_shuf rRIP, %ymm15, %ymm13; vbroadcasti128 (0 * 16)(%rdi), %ymm4; vpxor (0 * 16)(%rcx), %ymm5, %ymm0; vpxor (2 * 16)(%rcx), %ymm6, %ymm1; vpxor (4 * 16)(%rcx), %ymm7, %ymm2; vpxor (6 * 16)(%rcx), %ymm8, %ymm3; leaq (8 * 16)(%rcx), %rcx; .align 8 .Lxts_crypt_blk8_loop: cmpq $8, %r8; jb .Lxts_crypt_blk8_tail; leaq -8(%r8), %r8; testl %eax, %eax; jz .Lxts_dec_blk8; /* AES rounds */ XOR4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3); vbroadcasti128 (1 * 16)(%rdi), %ymm4; VAESENC4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3); vbroadcasti128 (2 * 16)(%rdi), %ymm4; VAESENC4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3); vbroadcasti128 (3 * 16)(%rdi), %ymm4; VAESENC4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3); vbroadcasti128 (4 * 16)(%rdi), %ymm4; VAESENC4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3); vmovdqa %ymm15, %ymm9; tweak_clmul(2, %ymm10, %ymm15, %ymm13, %ymm12, %ymm14); tweak_clmul(4, %ymm11, %ymm15, %ymm13, %ymm12, %ymm14); vbroadcasti128 (5 * 16)(%rdi), %ymm4; VAESENC4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3); vbroadcasti128 (6 * 16)(%rdi), %ymm4; VAESENC4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3); vbroadcasti128 (7 * 16)(%rdi), %ymm4; VAESENC4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3); vbroadcasti128 (8 * 16)(%rdi), %ymm4; VAESENC4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3); vbroadcasti128 (9 * 16)(%rdi), %ymm4; VAESENC4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3); vbroadcasti128 (10 * 16)(%rdi), %ymm4; cmpl $12, %r9d; jb .Lxts_enc_blk8_last; VAESENC4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3); vbroadcasti128 (11 * 16)(%rdi), %ymm4; VAESENC4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3); vbroadcasti128 (12 * 16)(%rdi), %ymm4; jz .Lxts_enc_blk8_last; VAESENC4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3); vbroadcasti128 (13 * 16)(%rdi), %ymm4; VAESENC4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3); vbroadcasti128 (14 * 16)(%rdi), %ymm4; /* Last round and output handling. */ .Lxts_enc_blk8_last: vpxor %ymm4, %ymm5, %ymm5; /* Xor tweak to last round key. */ vpxor %ymm4, %ymm6, %ymm6; vpxor %ymm4, %ymm7, %ymm7; vpxor %ymm4, %ymm8, %ymm4; tweak_clmul(6, %ymm8, %ymm15, %ymm13, %ymm12, %ymm14); tweak_clmul(8, %ymm15, %ymm15, %ymm13, %ymm12, %ymm14); vpshufb .Lxts_high_bit_shuf rRIP, %ymm15, %ymm13; vaesenclast %ymm5, %ymm0, %ymm0; vaesenclast %ymm6, %ymm1, %ymm1; vaesenclast %ymm7, %ymm2, %ymm2; vaesenclast %ymm4, %ymm3, %ymm3; vmovdqu %ymm0, (0 * 16)(%rdx); vmovdqu %ymm1, (2 * 16)(%rdx); vmovdqu %ymm2, (4 * 16)(%rdx); vmovdqu %ymm3, (6 * 16)(%rdx); leaq (8 * 16)(%rdx), %rdx; vbroadcasti128 (0 * 16)(%rdi), %ymm4; vpxor (0 * 16)(%rcx), %ymm9, %ymm0; vpxor (2 * 16)(%rcx), %ymm10, %ymm1; vpxor (4 * 16)(%rcx), %ymm11, %ymm2; vpxor (6 * 16)(%rcx), %ymm8, %ymm3; vmovdqa %ymm9, %ymm5; vmovdqa %ymm10, %ymm6; vmovdqa %ymm11, %ymm7; leaq (8 * 16)(%rcx), %rcx; jmp .Lxts_crypt_blk8_loop; .align 8 .Lxts_dec_blk8: /* AES rounds */ XOR4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3); vbroadcasti128 (1 * 16)(%rdi), %ymm4; VAESDEC4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3); vbroadcasti128 (2 * 16)(%rdi), %ymm4; VAESDEC4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3); vbroadcasti128 (3 * 16)(%rdi), %ymm4; VAESDEC4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3); vbroadcasti128 (4 * 16)(%rdi), %ymm4; VAESDEC4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3); vmovdqa %ymm15, %ymm9; tweak_clmul(2, %ymm10, %ymm15, %ymm13, %ymm12, %ymm14); tweak_clmul(4, %ymm11, %ymm15, %ymm13, %ymm12, %ymm14); vbroadcasti128 (5 * 16)(%rdi), %ymm4; VAESDEC4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3); vbroadcasti128 (6 * 16)(%rdi), %ymm4; VAESDEC4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3); vbroadcasti128 (7 * 16)(%rdi), %ymm4; VAESDEC4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3); vbroadcasti128 (8 * 16)(%rdi), %ymm4; VAESDEC4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3); vbroadcasti128 (9 * 16)(%rdi), %ymm4; VAESDEC4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3); vbroadcasti128 (10 * 16)(%rdi), %ymm4; cmpl $12, %r9d; jb .Lxts_dec_blk8_last; VAESDEC4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3); vbroadcasti128 (11 * 16)(%rdi), %ymm4; VAESDEC4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3); vbroadcasti128 (12 * 16)(%rdi), %ymm4; jz .Lxts_dec_blk8_last; VAESDEC4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3); vbroadcasti128 (13 * 16)(%rdi), %ymm4; VAESDEC4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3); vbroadcasti128 (14 * 16)(%rdi), %ymm4; /* Last round and output handling. */ .Lxts_dec_blk8_last: vpxor %ymm4, %ymm5, %ymm5; /* Xor tweak to last round key. */ vpxor %ymm4, %ymm6, %ymm6; vpxor %ymm4, %ymm7, %ymm7; vpxor %ymm4, %ymm8, %ymm4; tweak_clmul(6, %ymm8, %ymm15, %ymm13, %ymm12, %ymm14); tweak_clmul(8, %ymm15, %ymm15, %ymm13, %ymm12, %ymm14); vpshufb .Lxts_high_bit_shuf rRIP, %ymm15, %ymm13; vaesdeclast %ymm5, %ymm0, %ymm0; vaesdeclast %ymm6, %ymm1, %ymm1; vaesdeclast %ymm7, %ymm2, %ymm2; vaesdeclast %ymm4, %ymm3, %ymm3; vmovdqu %ymm0, (0 * 16)(%rdx); vmovdqu %ymm1, (2 * 16)(%rdx); vmovdqu %ymm2, (4 * 16)(%rdx); vmovdqu %ymm3, (6 * 16)(%rdx); leaq (8 * 16)(%rdx), %rdx; vbroadcasti128 (0 * 16)(%rdi), %ymm4; vpxor (0 * 16)(%rcx), %ymm9, %ymm0; vpxor (2 * 16)(%rcx), %ymm10, %ymm1; vpxor (4 * 16)(%rcx), %ymm11, %ymm2; vpxor (6 * 16)(%rcx), %ymm8, %ymm3; vmovdqa %ymm9, %ymm5; vmovdqa %ymm10, %ymm6; vmovdqa %ymm11, %ymm7; leaq (8 * 16)(%rcx), %rcx; jmp .Lxts_crypt_blk8_loop; .align 8 .Lxts_crypt_blk8_tail: testl %eax, %eax; jz .Lxts_dec_tail_blk8; /* AES rounds */ XOR4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3); vbroadcasti128 (1 * 16)(%rdi), %ymm4; VAESENC4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3); vbroadcasti128 (2 * 16)(%rdi), %ymm4; VAESENC4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3); vbroadcasti128 (3 * 16)(%rdi), %ymm4; VAESENC4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3); vbroadcasti128 (4 * 16)(%rdi), %ymm4; VAESENC4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3); vbroadcasti128 (5 * 16)(%rdi), %ymm4; VAESENC4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3); vbroadcasti128 (6 * 16)(%rdi), %ymm4; VAESENC4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3); vbroadcasti128 (7 * 16)(%rdi), %ymm4; VAESENC4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3); vbroadcasti128 (8 * 16)(%rdi), %ymm4; VAESENC4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3); vbroadcasti128 (9 * 16)(%rdi), %ymm4; VAESENC4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3); vbroadcasti128 (10 * 16)(%rdi), %ymm4; cmpl $12, %r9d; jb .Lxts_enc_blk8_tail_last; VAESENC4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3); vbroadcasti128 (11 * 16)(%rdi), %ymm4; VAESENC4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3); vbroadcasti128 (12 * 16)(%rdi), %ymm4; jz .Lxts_enc_blk8_tail_last; VAESENC4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3); vbroadcasti128 (13 * 16)(%rdi), %ymm4; VAESENC4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3); vbroadcasti128 (14 * 16)(%rdi), %ymm4; /* Last round and output handling. */ .Lxts_enc_blk8_tail_last: vpxor %ymm4, %ymm5, %ymm5; /* Xor tweak to last round key. */ vpxor %ymm4, %ymm6, %ymm6; vpxor %ymm4, %ymm7, %ymm7; vpxor %ymm4, %ymm8, %ymm4; vaesenclast %ymm5, %ymm0, %ymm0; vaesenclast %ymm6, %ymm1, %ymm1; vaesenclast %ymm7, %ymm2, %ymm2; vaesenclast %ymm4, %ymm3, %ymm3; vmovdqu %ymm0, (0 * 16)(%rdx); vmovdqu %ymm1, (2 * 16)(%rdx); vmovdqu %ymm2, (4 * 16)(%rdx); vmovdqu %ymm3, (6 * 16)(%rdx); leaq (8 * 16)(%rdx), %rdx; jmp .Lxts_crypt_blk4; .align 8 .Lxts_dec_tail_blk8: /* AES rounds */ XOR4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3); vbroadcasti128 (1 * 16)(%rdi), %ymm4; VAESDEC4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3); vbroadcasti128 (2 * 16)(%rdi), %ymm4; VAESDEC4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3); vbroadcasti128 (3 * 16)(%rdi), %ymm4; VAESDEC4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3); vbroadcasti128 (4 * 16)(%rdi), %ymm4; VAESDEC4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3); vbroadcasti128 (5 * 16)(%rdi), %ymm4; VAESDEC4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3); vbroadcasti128 (6 * 16)(%rdi), %ymm4; VAESDEC4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3); vbroadcasti128 (7 * 16)(%rdi), %ymm4; VAESDEC4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3); vbroadcasti128 (8 * 16)(%rdi), %ymm4; VAESDEC4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3); vbroadcasti128 (9 * 16)(%rdi), %ymm4; VAESDEC4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3); vbroadcasti128 (10 * 16)(%rdi), %ymm4; cmpl $12, %r9d; jb .Lxts_dec_blk8_tail_last; VAESDEC4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3); vbroadcasti128 (11 * 16)(%rdi), %ymm4; VAESDEC4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3); vbroadcasti128 (12 * 16)(%rdi), %ymm4; jz .Lxts_dec_blk8_tail_last; VAESDEC4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3); vbroadcasti128 (13 * 16)(%rdi), %ymm4; VAESDEC4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3); vbroadcasti128 (14 * 16)(%rdi), %ymm4; /* Last round and output handling. */ .Lxts_dec_blk8_tail_last: vpxor %ymm4, %ymm5, %ymm5; /* Xor tweak to last round key. */ vpxor %ymm4, %ymm6, %ymm6; vpxor %ymm4, %ymm7, %ymm7; vpxor %ymm4, %ymm8, %ymm4; vaesdeclast %ymm5, %ymm0, %ymm0; vaesdeclast %ymm6, %ymm1, %ymm1; vaesdeclast %ymm7, %ymm2, %ymm2; vaesdeclast %ymm4, %ymm3, %ymm3; vmovdqu %ymm0, (0 * 16)(%rdx); vmovdqu %ymm1, (2 * 16)(%rdx); vmovdqu %ymm2, (4 * 16)(%rdx); vmovdqu %ymm3, (6 * 16)(%rdx); leaq (8 * 16)(%rdx), %rdx; /* Handle trailing four blocks. */ .align 8 .Lxts_crypt_blk4: /* Try exit early as typically input length is large power of 2. */ cmpq $0, %r8; jb .Ldone_xts_crypt; cmpq $4, %r8; jb .Lxts_crypt_blk1; leaq -4(%r8), %r8; vmovdqa %ymm15, %ymm5; tweak_clmul(2, %ymm6, %ymm15, %ymm13, %ymm0, %ymm1); tweak_clmul(4, %ymm15, %ymm15, %ymm13, %ymm0, %ymm1); vpshufb .Lxts_high_bit_shuf rRIP, %ymm15, %ymm13; vbroadcasti128 (0 * 16)(%rdi), %ymm4; vpxor (0 * 16)(%rcx), %ymm5, %ymm0; vpxor (2 * 16)(%rcx), %ymm6, %ymm1; leaq (4 * 16)(%rcx), %rcx; testl %eax, %eax; jz .Lxts_dec_blk4; /* AES rounds */ XOR2(%ymm4, %ymm0, %ymm1); vbroadcasti128 (1 * 16)(%rdi), %ymm4; VAESENC2(%ymm4, %ymm0, %ymm1); vbroadcasti128 (2 * 16)(%rdi), %ymm4; VAESENC2(%ymm4, %ymm0, %ymm1); vbroadcasti128 (3 * 16)(%rdi), %ymm4; VAESENC2(%ymm4, %ymm0, %ymm1); vbroadcasti128 (4 * 16)(%rdi), %ymm4; VAESENC2(%ymm4, %ymm0, %ymm1); vbroadcasti128 (5 * 16)(%rdi), %ymm4; VAESENC2(%ymm4, %ymm0, %ymm1); vbroadcasti128 (6 * 16)(%rdi), %ymm4; VAESENC2(%ymm4, %ymm0, %ymm1); vbroadcasti128 (7 * 16)(%rdi), %ymm4; VAESENC2(%ymm4, %ymm0, %ymm1); vbroadcasti128 (8 * 16)(%rdi), %ymm4; VAESENC2(%ymm4, %ymm0, %ymm1); vbroadcasti128 (9 * 16)(%rdi), %ymm4; VAESENC2(%ymm4, %ymm0, %ymm1); vbroadcasti128 (10 * 16)(%rdi), %ymm4; cmpl $12, %r9d; jb .Lxts_enc_blk4_last; VAESENC2(%ymm4, %ymm0, %ymm1); vbroadcasti128 (11 * 16)(%rdi), %ymm4; VAESENC2(%ymm4, %ymm0, %ymm1); vbroadcasti128 (12 * 16)(%rdi), %ymm4; jz .Lxts_enc_blk4_last; VAESENC2(%ymm4, %ymm0, %ymm1); vbroadcasti128 (13 * 16)(%rdi), %ymm4; VAESENC2(%ymm4, %ymm0, %ymm1); vbroadcasti128 (14 * 16)(%rdi), %ymm4; /* Last round and output handling. */ .Lxts_enc_blk4_last: vpxor %ymm4, %ymm5, %ymm5; /* Xor tweak to last round key. */ vpxor %ymm4, %ymm6, %ymm6; vaesenclast %ymm5, %ymm0, %ymm0; vaesenclast %ymm6, %ymm1, %ymm1; vmovdqu %ymm0, (0 * 16)(%rdx); vmovdqu %ymm1, (2 * 16)(%rdx); leaq (4 * 16)(%rdx), %rdx; jmp .Lxts_crypt_blk1; .align 8 .Lxts_dec_blk4: /* AES rounds */ XOR2(%ymm4, %ymm0, %ymm1); vbroadcasti128 (1 * 16)(%rdi), %ymm4; VAESDEC2(%ymm4, %ymm0, %ymm1); vbroadcasti128 (2 * 16)(%rdi), %ymm4; VAESDEC2(%ymm4, %ymm0, %ymm1); vbroadcasti128 (3 * 16)(%rdi), %ymm4; VAESDEC2(%ymm4, %ymm0, %ymm1); vbroadcasti128 (4 * 16)(%rdi), %ymm4; VAESDEC2(%ymm4, %ymm0, %ymm1); vbroadcasti128 (5 * 16)(%rdi), %ymm4; VAESDEC2(%ymm4, %ymm0, %ymm1); vbroadcasti128 (6 * 16)(%rdi), %ymm4; VAESDEC2(%ymm4, %ymm0, %ymm1); vbroadcasti128 (7 * 16)(%rdi), %ymm4; VAESDEC2(%ymm4, %ymm0, %ymm1); vbroadcasti128 (8 * 16)(%rdi), %ymm4; VAESDEC2(%ymm4, %ymm0, %ymm1); vbroadcasti128 (9 * 16)(%rdi), %ymm4; VAESDEC2(%ymm4, %ymm0, %ymm1); vbroadcasti128 (10 * 16)(%rdi), %ymm4; cmpl $12, %r9d; jb .Lxts_dec_blk4_last; VAESDEC2(%ymm4, %ymm0, %ymm1); vbroadcasti128 (11 * 16)(%rdi), %ymm4; VAESDEC2(%ymm4, %ymm0, %ymm1); vbroadcasti128 (12 * 16)(%rdi), %ymm4; jz .Lxts_dec_blk4_last; VAESDEC2(%ymm4, %ymm0, %ymm1); vbroadcasti128 (13 * 16)(%rdi), %ymm4; VAESDEC2(%ymm4, %ymm0, %ymm1); vbroadcasti128 (14 * 16)(%rdi), %ymm4; /* Last round and output handling. */ .Lxts_dec_blk4_last: vpxor %ymm4, %ymm5, %ymm5; /* Xor tweak to last round key. */ vpxor %ymm4, %ymm6, %ymm6; vaesdeclast %ymm5, %ymm0, %ymm0; vaesdeclast %ymm6, %ymm1, %ymm1; vmovdqu %ymm0, (0 * 16)(%rdx); vmovdqu %ymm1, (2 * 16)(%rdx); leaq (4 * 16)(%rdx), %rdx; /* Process trailing one to three blocks, one per loop. */ .align 8 .Lxts_crypt_blk1: cmpq $1, %r8; jb .Ldone_xts_crypt; leaq -1(%r8), %r8; vpxor (%rcx), %xmm15, %xmm0; vmovdqa %xmm15, %xmm5; tweak_clmul(1, %xmm15, %xmm15, %xmm13, %xmm2, %xmm3); vpshufb .Lxts_high_bit_shuf rRIP, %xmm15, %xmm13; leaq 16(%rcx), %rcx; testl %eax, %eax; jz .Lxts_dec_blk1; /* AES rounds. */ vpxor (0 * 16)(%rdi), %xmm0, %xmm0; vaesenc (1 * 16)(%rdi), %xmm0, %xmm0; vaesenc (2 * 16)(%rdi), %xmm0, %xmm0; vaesenc (3 * 16)(%rdi), %xmm0, %xmm0; vaesenc (4 * 16)(%rdi), %xmm0, %xmm0; vaesenc (5 * 16)(%rdi), %xmm0, %xmm0; vaesenc (6 * 16)(%rdi), %xmm0, %xmm0; vaesenc (7 * 16)(%rdi), %xmm0, %xmm0; vaesenc (8 * 16)(%rdi), %xmm0, %xmm0; vaesenc (9 * 16)(%rdi), %xmm0, %xmm0; vmovdqa (10 * 16)(%rdi), %xmm1; cmpl $12, %r9d; jb .Lxts_enc_blk1_last; vaesenc %xmm1, %xmm0, %xmm0; vaesenc (11 * 16)(%rdi), %xmm0, %xmm0; vmovdqa (12 * 16)(%rdi), %xmm1; jz .Lxts_enc_blk1_last; vaesenc %xmm1, %xmm0, %xmm0; vaesenc (13 * 16)(%rdi), %xmm0, %xmm0; vmovdqa (14 * 16)(%rdi), %xmm1; /* Last round and output handling. */ .Lxts_enc_blk1_last: vpxor %xmm1, %xmm5, %xmm5; /* Xor tweak to last round key. */ vaesenclast %xmm5, %xmm0, %xmm0; vmovdqu %xmm0, (%rdx); leaq 16(%rdx), %rdx; jmp .Lxts_crypt_blk1; .align 8 .Lxts_dec_blk1: /* AES rounds. */ vpxor (0 * 16)(%rdi), %xmm0, %xmm0; vaesdec (1 * 16)(%rdi), %xmm0, %xmm0; vaesdec (2 * 16)(%rdi), %xmm0, %xmm0; vaesdec (3 * 16)(%rdi), %xmm0, %xmm0; vaesdec (4 * 16)(%rdi), %xmm0, %xmm0; vaesdec (5 * 16)(%rdi), %xmm0, %xmm0; vaesdec (6 * 16)(%rdi), %xmm0, %xmm0; vaesdec (7 * 16)(%rdi), %xmm0, %xmm0; vaesdec (8 * 16)(%rdi), %xmm0, %xmm0; vaesdec (9 * 16)(%rdi), %xmm0, %xmm0; vmovdqa (10 * 16)(%rdi), %xmm1; cmpl $12, %r9d; jb .Lxts_dec_blk1_last; vaesdec %xmm1, %xmm0, %xmm0; vaesdec (11 * 16)(%rdi), %xmm0, %xmm0; vmovdqa (12 * 16)(%rdi), %xmm1; jz .Lxts_dec_blk1_last; vaesdec %xmm1, %xmm0, %xmm0; vaesdec (13 * 16)(%rdi), %xmm0, %xmm0; vmovdqa (14 * 16)(%rdi), %xmm1; /* Last round and output handling. */ .Lxts_dec_blk1_last: vpxor %xmm1, %xmm5, %xmm5; /* Xor tweak to last round key. */ vaesdeclast %xmm5, %xmm0, %xmm0; vmovdqu %xmm0, (%rdx); leaq 16(%rdx), %rdx; jmp .Lxts_crypt_blk1; .align 8 .Ldone_xts_crypt: /* Store IV. */ vmovdqu %xmm15, (%rsi); vzeroall; xorl %eax, %eax ret CFI_ENDPROC(); ELF(.size _gcry_vaes_avx2_xts_crypt_amd64,.-_gcry_vaes_avx2_xts_crypt_amd64) /********************************************************************** constants **********************************************************************/ ELF(.type _gcry_vaes_consts,@object) _gcry_vaes_consts: .align 32 .Lbige_addb_0: .byte 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 .Lbige_addb_1: .byte 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 .Lbige_addb_2: .byte 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2 .Lbige_addb_3: .byte 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3 .Lbige_addb_4: .byte 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4 .Lbige_addb_5: .byte 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5 .Lbige_addb_6: .byte 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6 .Lbige_addb_7: .byte 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7 .Lbige_addb_8: .byte 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8 .Lbige_addb_9: .byte 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9 .Lbige_addb_10: .byte 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10 .Lbige_addb_11: .byte 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11 .Lbige_addb_12: .byte 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12 .Lbige_addb_13: .byte 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13 .Lbige_addb_14: .byte 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14 .Lbige_addb_15: .byte 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15 + +.Lle_addd_0: + .byte 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +.Lle_addd_1: + .byte 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +.Lle_addd_2: + .byte 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +.Lle_addd_3: + .byte 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +.Lle_addd_4: + .byte 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +.Lle_addd_5: + .byte 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +.Lle_addd_6: + .byte 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +.Lle_addd_7: + .byte 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +.Lle_addd_8: + .byte 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +.Lle_addd_9: + .byte 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +.Lle_addd_10: + .byte 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +.Lle_addd_11: + .byte 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +.Lle_addd_12: + .byte 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +.Lle_addd_13: + .byte 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +.Lle_addd_14: + .byte 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +.Lle_addd_15: + .byte 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + +.Lle_addd_4_2: + .byte 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + .byte 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +.Lle_addd_8_2: + .byte 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + .byte 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +.Lle_addd_16_2: + .byte 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + .byte 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + .Lxts_gfmul_clmul: .long 0x00, 0x87, 0x00, 0x00 .long 0x00, 0x87, 0x00, 0x00 .Lxts_high_bit_shuf: .byte -1, -1, -1, -1, 12, 13, 14, 15 .byte 4, 5, 6, 7, -1, -1, -1, -1 .byte -1, -1, -1, -1, 12, 13, 14, 15 .byte 4, 5, 6, 7, -1, -1, -1, -1 .Lbswap128_mask: .byte 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 ELF(.size _gcry_vaes_consts,.-_gcry_vaes_consts) #endif /* HAVE_GCC_INLINE_ASM_VAES */ #endif /* __x86_64__ */ diff --git a/cipher/rijndael-vaes.c b/cipher/rijndael-vaes.c index 56afce17..0d7d1367 100644 --- a/cipher/rijndael-vaes.c +++ b/cipher/rijndael-vaes.c @@ -1,176 +1,197 @@ /* VAES/AVX2 accelerated AES for Libgcrypt * Copyright (C) 2021 Jussi Kivilinna * * This file is part of Libgcrypt. * * Libgcrypt is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * Libgcrypt is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this program; if not, see . * */ #include #include #include #include "types.h" /* for byte and u32 typedefs */ #include "g10lib.h" #include "cipher.h" #include "bufhelp.h" #include "cipher-selftest.h" #include "rijndael-internal.h" #include "./cipher-internal.h" #ifdef USE_VAES # ifdef HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS # define ASM_FUNC_ABI __attribute__((sysv_abi)) # else # define ASM_FUNC_ABI # endif extern void _gcry_aes_aesni_prepare_decryption(RIJNDAEL_context *ctx); extern void _gcry_vaes_avx2_cbc_dec_amd64 (const void *keysched, unsigned char *iv, void *outbuf_arg, const void *inbuf_arg, size_t nblocks, unsigned int nrounds) ASM_FUNC_ABI; extern void _gcry_vaes_avx2_cfb_dec_amd64 (const void *keysched, unsigned char *iv, void *outbuf_arg, const void *inbuf_arg, size_t nblocks, unsigned int nrounds) ASM_FUNC_ABI; extern void _gcry_vaes_avx2_ctr_enc_amd64 (const void *keysched, unsigned char *ctr, void *outbuf_arg, const void *inbuf_arg, size_t nblocks, unsigned int nrounds) ASM_FUNC_ABI; +extern void _gcry_vaes_avx2_ctr32le_enc_amd64 (const void *keysched, + unsigned char *ctr, + void *outbuf_arg, + const void *inbuf_arg, + size_t nblocks, + unsigned int nrounds) + ASM_FUNC_ABI; + extern void _gcry_vaes_avx2_ocb_crypt_amd64 (const void *keysched, unsigned int blkn, void *outbuf_arg, const void *inbuf_arg, size_t nblocks, unsigned int nrounds, unsigned char *offset, unsigned char *checksum, unsigned char *L_table, int encrypt) ASM_FUNC_ABI; extern void _gcry_vaes_avx2_xts_crypt_amd64 (const void *keysched, unsigned char *tweak, void *outbuf_arg, const void *inbuf_arg, size_t nblocks, unsigned int nrounds, int encrypt) ASM_FUNC_ABI; void _gcry_aes_vaes_cbc_dec (void *context, unsigned char *iv, void *outbuf, const void *inbuf, size_t nblocks) { RIJNDAEL_context *ctx = context; const void *keysched = ctx->keyschdec32; unsigned int nrounds = ctx->rounds; if (!ctx->decryption_prepared) { _gcry_aes_aesni_prepare_decryption (ctx); ctx->decryption_prepared = 1; } _gcry_vaes_avx2_cbc_dec_amd64 (keysched, iv, outbuf, inbuf, nblocks, nrounds); } void _gcry_aes_vaes_cfb_dec (void *context, unsigned char *iv, void *outbuf, const void *inbuf, size_t nblocks) { RIJNDAEL_context *ctx = context; const void *keysched = ctx->keyschenc32; unsigned int nrounds = ctx->rounds; _gcry_vaes_avx2_cfb_dec_amd64 (keysched, iv, outbuf, inbuf, nblocks, nrounds); } void _gcry_aes_vaes_ctr_enc (void *context, unsigned char *iv, void *outbuf, const void *inbuf, size_t nblocks) { RIJNDAEL_context *ctx = context; const void *keysched = ctx->keyschenc32; unsigned int nrounds = ctx->rounds; _gcry_vaes_avx2_ctr_enc_amd64 (keysched, iv, outbuf, inbuf, nblocks, nrounds); } +void +_gcry_aes_vaes_ctr32le_enc (void *context, unsigned char *iv, + void *outbuf, const void *inbuf, + size_t nblocks) +{ + RIJNDAEL_context *ctx = context; + const void *keysched = ctx->keyschenc32; + unsigned int nrounds = ctx->rounds; + + _gcry_vaes_avx2_ctr32le_enc_amd64 (keysched, iv, outbuf, inbuf, nblocks, + nrounds); +} + size_t _gcry_aes_vaes_ocb_crypt (gcry_cipher_hd_t c, void *outbuf_arg, const void *inbuf_arg, size_t nblocks, int encrypt) { RIJNDAEL_context *ctx = (void *)&c->context.c; const void *keysched = encrypt ? ctx->keyschenc32 : ctx->keyschdec32; unsigned char *outbuf = outbuf_arg; const unsigned char *inbuf = inbuf_arg; unsigned int nrounds = ctx->rounds; u64 blkn = c->u_mode.ocb.data_nblocks; if (!encrypt && !ctx->decryption_prepared) { _gcry_aes_aesni_prepare_decryption (ctx); ctx->decryption_prepared = 1; } c->u_mode.ocb.data_nblocks = blkn + nblocks; _gcry_vaes_avx2_ocb_crypt_amd64 (keysched, (unsigned int)blkn, outbuf, inbuf, nblocks, nrounds, c->u_iv.iv, c->u_ctr.ctr, c->u_mode.ocb.L[0], encrypt); return 0; } void _gcry_aes_vaes_xts_crypt (void *context, unsigned char *tweak, void *outbuf, const void *inbuf, size_t nblocks, int encrypt) { RIJNDAEL_context *ctx = context; const void *keysched = encrypt ? ctx->keyschenc32 : ctx->keyschdec32; unsigned int nrounds = ctx->rounds; if (!encrypt && !ctx->decryption_prepared) { _gcry_aes_aesni_prepare_decryption (ctx); ctx->decryption_prepared = 1; } _gcry_vaes_avx2_xts_crypt_amd64 (keysched, tweak, outbuf, inbuf, nblocks, nrounds, encrypt); } #endif /* USE_VAES */ diff --git a/cipher/rijndael.c b/cipher/rijndael.c index 8df9aac3..c096321f 100644 --- a/cipher/rijndael.c +++ b/cipher/rijndael.c @@ -1,2083 +1,2091 @@ /* Rijndael (AES) for GnuPG * Copyright (C) 2000, 2001, 2002, 2003, 2007, * 2008, 2011, 2012 Free Software Foundation, Inc. * * This file is part of Libgcrypt. * * Libgcrypt is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * Libgcrypt is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this program; if not, see . ******************************************************************* * The code here is based on the optimized implementation taken from * http://www.esat.kuleuven.ac.be/~rijmen/rijndael/ on Oct 2, 2000, * which carries this notice: *------------------------------------------ * rijndael-alg-fst.c v2.3 April '2000 * * Optimised ANSI C code * * authors: v1.0: Antoon Bosselaers * v2.0: Vincent Rijmen * v2.3: Paulo Barreto * * This code is placed in the public domain. *------------------------------------------ * * The SP800-38a document is available at: * http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf * */ #include #include #include #include /* for memcmp() */ #include "types.h" /* for byte and u32 typedefs */ #include "g10lib.h" #include "cipher.h" #include "bufhelp.h" #include "cipher-selftest.h" #include "rijndael-internal.h" #include "./cipher-internal.h" #ifdef USE_AMD64_ASM /* AMD64 assembly implementations of AES */ extern unsigned int _gcry_aes_amd64_encrypt_block(const void *keysched_enc, unsigned char *out, const unsigned char *in, int rounds, const void *encT); extern unsigned int _gcry_aes_amd64_decrypt_block(const void *keysched_dec, unsigned char *out, const unsigned char *in, int rounds, const void *decT); #endif /*USE_AMD64_ASM*/ #ifdef USE_AESNI /* AES-NI (AMD64 & i386) accelerated implementations of AES */ extern void _gcry_aes_aesni_do_setkey(RIJNDAEL_context *ctx, const byte *key); extern void _gcry_aes_aesni_prepare_decryption(RIJNDAEL_context *ctx); extern unsigned int _gcry_aes_aesni_encrypt (const RIJNDAEL_context *ctx, unsigned char *dst, const unsigned char *src); extern unsigned int _gcry_aes_aesni_decrypt (const RIJNDAEL_context *ctx, unsigned char *dst, const unsigned char *src); extern void _gcry_aes_aesni_cfb_enc (void *context, unsigned char *iv, void *outbuf_arg, const void *inbuf_arg, size_t nblocks); extern void _gcry_aes_aesni_cbc_enc (void *context, unsigned char *iv, void *outbuf_arg, const void *inbuf_arg, size_t nblocks, int cbc_mac); extern void _gcry_aes_aesni_ctr_enc (void *context, unsigned char *ctr, void *outbuf_arg, const void *inbuf_arg, size_t nblocks); +extern void _gcry_aes_aesni_ctr32le_enc (void *context, unsigned char *ctr, + void *outbuf_arg, + const void *inbuf_arg, size_t nblocks); extern void _gcry_aes_aesni_cfb_dec (void *context, unsigned char *iv, void *outbuf_arg, const void *inbuf_arg, size_t nblocks); extern void _gcry_aes_aesni_cbc_dec (void *context, unsigned char *iv, void *outbuf_arg, const void *inbuf_arg, size_t nblocks); extern size_t _gcry_aes_aesni_ocb_crypt (gcry_cipher_hd_t c, void *outbuf_arg, const void *inbuf_arg, size_t nblocks, int encrypt); extern size_t _gcry_aes_aesni_ocb_auth (gcry_cipher_hd_t c, const void *abuf_arg, size_t nblocks); extern void _gcry_aes_aesni_xts_crypt (void *context, unsigned char *tweak, void *outbuf_arg, const void *inbuf_arg, size_t nblocks, int encrypt); #endif #ifdef USE_VAES /* VAES (AMD64) accelerated implementation of AES */ extern void _gcry_aes_vaes_cfb_dec (void *context, unsigned char *iv, void *outbuf_arg, const void *inbuf_arg, size_t nblocks); extern void _gcry_aes_vaes_cbc_dec (void *context, unsigned char *iv, void *outbuf_arg, const void *inbuf_arg, size_t nblocks); extern void _gcry_aes_vaes_ctr_enc (void *context, unsigned char *ctr, void *outbuf_arg, const void *inbuf_arg, size_t nblocks); +extern void _gcry_aes_vaes_ctr32le_enc (void *context, unsigned char *ctr, + void *outbuf_arg, const void *inbuf_arg, + size_t nblocks); extern size_t _gcry_aes_vaes_ocb_crypt (gcry_cipher_hd_t c, void *outbuf_arg, const void *inbuf_arg, size_t nblocks, int encrypt); extern void _gcry_aes_vaes_xts_crypt (void *context, unsigned char *tweak, void *outbuf_arg, const void *inbuf_arg, size_t nblocks, int encrypt); #endif #ifdef USE_SSSE3 /* SSSE3 (AMD64) vector permutation implementation of AES */ extern void _gcry_aes_ssse3_do_setkey(RIJNDAEL_context *ctx, const byte *key); extern void _gcry_aes_ssse3_prepare_decryption(RIJNDAEL_context *ctx); extern unsigned int _gcry_aes_ssse3_encrypt (const RIJNDAEL_context *ctx, unsigned char *dst, const unsigned char *src); extern unsigned int _gcry_aes_ssse3_decrypt (const RIJNDAEL_context *ctx, unsigned char *dst, const unsigned char *src); extern void _gcry_aes_ssse3_cfb_enc (void *context, unsigned char *iv, void *outbuf_arg, const void *inbuf_arg, size_t nblocks); extern void _gcry_aes_ssse3_cbc_enc (void *context, unsigned char *iv, void *outbuf_arg, const void *inbuf_arg, size_t nblocks, int cbc_mac); extern void _gcry_aes_ssse3_ctr_enc (void *context, unsigned char *ctr, void *outbuf_arg, const void *inbuf_arg, size_t nblocks); extern void _gcry_aes_ssse3_cfb_dec (void *context, unsigned char *iv, void *outbuf_arg, const void *inbuf_arg, size_t nblocks); extern void _gcry_aes_ssse3_cbc_dec (void *context, unsigned char *iv, void *outbuf_arg, const void *inbuf_arg, size_t nblocks); extern size_t _gcry_aes_ssse3_ocb_crypt (gcry_cipher_hd_t c, void *outbuf_arg, const void *inbuf_arg, size_t nblocks, int encrypt); extern size_t _gcry_aes_ssse3_ocb_auth (gcry_cipher_hd_t c, const void *abuf_arg, size_t nblocks); #endif #ifdef USE_PADLOCK extern unsigned int _gcry_aes_padlock_encrypt (const RIJNDAEL_context *ctx, unsigned char *bx, const unsigned char *ax); extern unsigned int _gcry_aes_padlock_decrypt (const RIJNDAEL_context *ctx, unsigned char *bx, const unsigned char *ax); extern void _gcry_aes_padlock_prepare_decryption (RIJNDAEL_context *ctx); #endif #ifdef USE_ARM_ASM /* ARM assembly implementations of AES */ extern unsigned int _gcry_aes_arm_encrypt_block(const void *keysched_enc, unsigned char *out, const unsigned char *in, int rounds, const void *encT); extern unsigned int _gcry_aes_arm_decrypt_block(const void *keysched_dec, unsigned char *out, const unsigned char *in, int rounds, const void *decT); #endif /*USE_ARM_ASM*/ #ifdef USE_ARM_CE /* ARMv8 Crypto Extension implementations of AES */ extern void _gcry_aes_armv8_ce_setkey(RIJNDAEL_context *ctx, const byte *key); extern void _gcry_aes_armv8_ce_prepare_decryption(RIJNDAEL_context *ctx); extern unsigned int _gcry_aes_armv8_ce_encrypt(const RIJNDAEL_context *ctx, unsigned char *dst, const unsigned char *src); extern unsigned int _gcry_aes_armv8_ce_decrypt(const RIJNDAEL_context *ctx, unsigned char *dst, const unsigned char *src); extern void _gcry_aes_armv8_ce_cfb_enc (void *context, unsigned char *iv, void *outbuf_arg, const void *inbuf_arg, size_t nblocks); extern void _gcry_aes_armv8_ce_cbc_enc (void *context, unsigned char *iv, void *outbuf_arg, const void *inbuf_arg, size_t nblocks, int cbc_mac); extern void _gcry_aes_armv8_ce_ctr_enc (void *context, unsigned char *ctr, void *outbuf_arg, const void *inbuf_arg, size_t nblocks); extern void _gcry_aes_armv8_ce_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->ctr32le_enc = _gcry_aes_aesni_ctr32le_enc; bulk_ops->ocb_crypt = _gcry_aes_aesni_ocb_crypt; bulk_ops->ocb_auth = _gcry_aes_aesni_ocb_auth; bulk_ops->xts_crypt = _gcry_aes_aesni_xts_crypt; #ifdef USE_VAES if ((hwfeatures & HWF_INTEL_VAES_VPCLMUL) && (hwfeatures & HWF_INTEL_AVX2)) { /* Setup VAES bulk encryption routines. */ bulk_ops->cfb_dec = _gcry_aes_vaes_cfb_dec; bulk_ops->cbc_dec = _gcry_aes_vaes_cbc_dec; bulk_ops->ctr_enc = _gcry_aes_vaes_ctr_enc; + bulk_ops->ctr32le_enc = _gcry_aes_vaes_ctr32le_enc; bulk_ops->ocb_crypt = _gcry_aes_vaes_ocb_crypt; bulk_ops->xts_crypt = _gcry_aes_vaes_xts_crypt; } #endif } #endif #ifdef USE_PADLOCK - else if (hwfeatures & HWF_PADLOCK_AES && keylen == 128/8) + 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) { #ifdef USE_VAES const int nblocks = 16+1; #else const int nblocks = 8+1; #endif const int blocksize = BLOCKSIZE; const int context_size = sizeof(RIJNDAEL_context); return _gcry_selftest_helper_ctr("AES", &rijndael_setkey, &rijndael_encrypt, nblocks, blocksize, context_size); } /* Run the self-tests for AES-CBC-128, tests bulk CBC decryption. Returns NULL on success. */ static const char* selftest_cbc_128 (void) { #ifdef USE_VAES const int nblocks = 16+2; #else const int nblocks = 8+2; #endif const int blocksize = BLOCKSIZE; const int context_size = sizeof(RIJNDAEL_context); return _gcry_selftest_helper_cbc("AES", &rijndael_setkey, &rijndael_encrypt, nblocks, blocksize, context_size); } /* Run the self-tests for AES-CFB-128, tests bulk CFB decryption. Returns NULL on success. */ static const char* selftest_cfb_128 (void) { #ifdef USE_VAES const int nblocks = 16+2; #else const int nblocks = 8+2; #endif const int blocksize = BLOCKSIZE; const int context_size = sizeof(RIJNDAEL_context); return _gcry_selftest_helper_cfb("AES", &rijndael_setkey, &rijndael_encrypt, nblocks, blocksize, context_size); } /* Run all the self-tests and return NULL on success. This function is used for the on-the-fly self-tests. */ static const char * selftest (void) { const char *r; if ( (r = selftest_basic_128 ()) || (r = selftest_basic_192 ()) || (r = selftest_basic_256 ()) ) return r; if ( (r = selftest_ctr_128 ()) ) return r; if ( (r = selftest_cbc_128 ()) ) return r; if ( (r = selftest_cfb_128 ()) ) return r; return r; } /* SP800-38a.pdf for AES-128. */ static const char * selftest_fips_128_38a (int requested_mode) { static const struct tv { int mode; const unsigned char key[16]; const unsigned char iv[16]; struct { const unsigned char input[16]; const unsigned char output[16]; } data[4]; } tv[2] = { { GCRY_CIPHER_MODE_CFB, /* F.3.13, CFB128-AES128 */ { 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c }, { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }, { { { 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a }, { 0x3b, 0x3f, 0xd9, 0x2e, 0xb7, 0x2d, 0xad, 0x20, 0x33, 0x34, 0x49, 0xf8, 0xe8, 0x3c, 0xfb, 0x4a } }, { { 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c, 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51 }, { 0xc8, 0xa6, 0x45, 0x37, 0xa0, 0xb3, 0xa9, 0x3f, 0xcd, 0xe3, 0xcd, 0xad, 0x9f, 0x1c, 0xe5, 0x8b } }, { { 0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11, 0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef }, { 0x26, 0x75, 0x1f, 0x67, 0xa3, 0xcb, 0xb1, 0x40, 0xb1, 0x80, 0x8c, 0xf1, 0x87, 0xa4, 0xf4, 0xdf } }, { { 0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17, 0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10 }, { 0xc0, 0x4b, 0x05, 0x35, 0x7c, 0x5d, 0x1c, 0x0e, 0xea, 0xc4, 0xc6, 0x6f, 0x9f, 0xf7, 0xf2, 0xe6 } } } }, { GCRY_CIPHER_MODE_OFB, { 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c }, { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }, { { { 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a }, { 0x3b, 0x3f, 0xd9, 0x2e, 0xb7, 0x2d, 0xad, 0x20, 0x33, 0x34, 0x49, 0xf8, 0xe8, 0x3c, 0xfb, 0x4a } }, { { 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c, 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51 }, { 0x77, 0x89, 0x50, 0x8d, 0x16, 0x91, 0x8f, 0x03, 0xf5, 0x3c, 0x52, 0xda, 0xc5, 0x4e, 0xd8, 0x25 } }, { { 0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11, 0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef }, { 0x97, 0x40, 0x05, 0x1e, 0x9c, 0x5f, 0xec, 0xf6, 0x43, 0x44, 0xf7, 0xa8, 0x22, 0x60, 0xed, 0xcc } }, { { 0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17, 0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10 }, { 0x30, 0x4c, 0x65, 0x28, 0xf6, 0x59, 0xc7, 0x78, 0x66, 0xa5, 0x10, 0xd9, 0xc1, 0xd6, 0xae, 0x5e } }, } } }; unsigned char scratch[16]; gpg_error_t err; int tvi, idx; gcry_cipher_hd_t hdenc = NULL; gcry_cipher_hd_t hddec = NULL; #define Fail(a) do { \ _gcry_cipher_close (hdenc); \ _gcry_cipher_close (hddec); \ return a; \ } while (0) gcry_assert (sizeof tv[0].data[0].input == sizeof scratch); gcry_assert (sizeof tv[0].data[0].output == sizeof scratch); for (tvi=0; tvi < DIM (tv); tvi++) if (tv[tvi].mode == requested_mode) break; if (tvi == DIM (tv)) Fail ("no test data for this mode"); err = _gcry_cipher_open (&hdenc, GCRY_CIPHER_AES, tv[tvi].mode, 0); if (err) Fail ("open"); err = _gcry_cipher_open (&hddec, GCRY_CIPHER_AES, tv[tvi].mode, 0); if (err) Fail ("open"); err = _gcry_cipher_setkey (hdenc, tv[tvi].key, sizeof tv[tvi].key); if (!err) err = _gcry_cipher_setkey (hddec, tv[tvi].key, sizeof tv[tvi].key); if (err) Fail ("set key"); err = _gcry_cipher_setiv (hdenc, tv[tvi].iv, sizeof tv[tvi].iv); if (!err) err = _gcry_cipher_setiv (hddec, tv[tvi].iv, sizeof tv[tvi].iv); if (err) Fail ("set IV"); for (idx=0; idx < DIM (tv[tvi].data); idx++) { err = _gcry_cipher_encrypt (hdenc, scratch, sizeof scratch, tv[tvi].data[idx].input, sizeof tv[tvi].data[idx].input); if (err) Fail ("encrypt command"); if (memcmp (scratch, tv[tvi].data[idx].output, sizeof scratch)) Fail ("encrypt mismatch"); err = _gcry_cipher_decrypt (hddec, scratch, sizeof scratch, tv[tvi].data[idx].output, sizeof tv[tvi].data[idx].output); if (err) Fail ("decrypt command"); if (memcmp (scratch, tv[tvi].data[idx].input, sizeof scratch)) Fail ("decrypt mismatch"); } #undef Fail _gcry_cipher_close (hdenc); _gcry_cipher_close (hddec); return NULL; } /* Complete selftest for AES-128 with all modes and driver code. */ static gpg_err_code_t selftest_fips_128 (int extended, selftest_report_func_t report) { const char *what; const char *errtxt; what = "low-level"; errtxt = selftest_basic_128 (); if (errtxt) goto failed; if (extended) { what = "cfb"; errtxt = selftest_fips_128_38a (GCRY_CIPHER_MODE_CFB); if (errtxt) goto failed; what = "ofb"; errtxt = selftest_fips_128_38a (GCRY_CIPHER_MODE_OFB); if (errtxt) goto failed; } return 0; /* Succeeded. */ failed: if (report) report ("cipher", GCRY_CIPHER_AES128, what, errtxt); return GPG_ERR_SELFTEST_FAILED; } /* Complete selftest for AES-192. */ static gpg_err_code_t selftest_fips_192 (int extended, selftest_report_func_t report) { const char *what; const char *errtxt; (void)extended; /* No extended tests available. */ what = "low-level"; errtxt = selftest_basic_192 (); if (errtxt) goto failed; return 0; /* Succeeded. */ failed: if (report) report ("cipher", GCRY_CIPHER_AES192, what, errtxt); return GPG_ERR_SELFTEST_FAILED; } /* Complete selftest for AES-256. */ static gpg_err_code_t selftest_fips_256 (int extended, selftest_report_func_t report) { const char *what; const char *errtxt; (void)extended; /* No extended tests available. */ what = "low-level"; errtxt = selftest_basic_256 (); if (errtxt) goto failed; return 0; /* Succeeded. */ failed: if (report) report ("cipher", GCRY_CIPHER_AES256, what, errtxt); return GPG_ERR_SELFTEST_FAILED; } /* Run a full self-test for ALGO and return 0 on success. */ static gpg_err_code_t run_selftests (int algo, int extended, selftest_report_func_t report) { gpg_err_code_t ec; switch (algo) { case GCRY_CIPHER_AES128: ec = selftest_fips_128 (extended, report); break; case GCRY_CIPHER_AES192: ec = selftest_fips_192 (extended, report); break; case GCRY_CIPHER_AES256: ec = selftest_fips_256 (extended, report); break; default: ec = GPG_ERR_CIPHER_ALGO; break; } return ec; } static const char *rijndael_names[] = { "RIJNDAEL", "AES128", "AES-128", NULL }; static gcry_cipher_oid_spec_t rijndael_oids[] = { { "2.16.840.1.101.3.4.1.1", GCRY_CIPHER_MODE_ECB }, { "2.16.840.1.101.3.4.1.2", GCRY_CIPHER_MODE_CBC }, { "2.16.840.1.101.3.4.1.3", GCRY_CIPHER_MODE_OFB }, { "2.16.840.1.101.3.4.1.4", GCRY_CIPHER_MODE_CFB }, { "2.16.840.1.101.3.4.1.6", GCRY_CIPHER_MODE_GCM }, { "2.16.840.1.101.3.4.1.7", GCRY_CIPHER_MODE_CCM }, { NULL } }; gcry_cipher_spec_t _gcry_cipher_spec_aes = { GCRY_CIPHER_AES, {0, 1}, "AES", rijndael_names, rijndael_oids, 16, 128, sizeof (RIJNDAEL_context), rijndael_setkey, rijndael_encrypt, rijndael_decrypt, NULL, NULL, run_selftests }; static const char *rijndael192_names[] = { "RIJNDAEL192", "AES-192", NULL }; static gcry_cipher_oid_spec_t rijndael192_oids[] = { { "2.16.840.1.101.3.4.1.21", GCRY_CIPHER_MODE_ECB }, { "2.16.840.1.101.3.4.1.22", GCRY_CIPHER_MODE_CBC }, { "2.16.840.1.101.3.4.1.23", GCRY_CIPHER_MODE_OFB }, { "2.16.840.1.101.3.4.1.24", GCRY_CIPHER_MODE_CFB }, { "2.16.840.1.101.3.4.1.26", GCRY_CIPHER_MODE_GCM }, { "2.16.840.1.101.3.4.1.27", GCRY_CIPHER_MODE_CCM }, { NULL } }; gcry_cipher_spec_t _gcry_cipher_spec_aes192 = { GCRY_CIPHER_AES192, {0, 1}, "AES192", rijndael192_names, rijndael192_oids, 16, 192, sizeof (RIJNDAEL_context), rijndael_setkey, rijndael_encrypt, rijndael_decrypt, NULL, NULL, run_selftests }; static const char *rijndael256_names[] = { "RIJNDAEL256", "AES-256", NULL }; static gcry_cipher_oid_spec_t rijndael256_oids[] = { { "2.16.840.1.101.3.4.1.41", GCRY_CIPHER_MODE_ECB }, { "2.16.840.1.101.3.4.1.42", GCRY_CIPHER_MODE_CBC }, { "2.16.840.1.101.3.4.1.43", GCRY_CIPHER_MODE_OFB }, { "2.16.840.1.101.3.4.1.44", GCRY_CIPHER_MODE_CFB }, { "2.16.840.1.101.3.4.1.46", GCRY_CIPHER_MODE_GCM }, { "2.16.840.1.101.3.4.1.47", GCRY_CIPHER_MODE_CCM }, { NULL } }; gcry_cipher_spec_t _gcry_cipher_spec_aes256 = { GCRY_CIPHER_AES256, {0, 1}, "AES256", rijndael256_names, rijndael256_oids, 16, 256, sizeof (RIJNDAEL_context), rijndael_setkey, rijndael_encrypt, rijndael_decrypt, NULL, NULL, run_selftests }; diff --git a/tests/basic.c b/tests/basic.c index 148aaec6..4ce90165 100644 --- a/tests/basic.c +++ b/tests/basic.c @@ -1,16023 +1,16162 @@ /* basic.c - basic regression tests * Copyright (C) 2001, 2002, 2003, 2005, 2008, * 2009 Free Software Foundation, Inc. * Copyright (C) 2013 g10 Code GmbH * * This file is part of Libgcrypt. * * Libgcrypt is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * Libgcrypt is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this program; if not, see . */ #ifdef HAVE_CONFIG_H #include #endif #include #include #include #include #include #include "../src/gcrypt-int.h" #define PGM "basic" #include "t-common.h" #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 ( "", 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" }, { GCRY_CIPHER_AES256, "\xfe\xff\xe9\x92\x86\x65\x73\x1c\x6d\x6a\x8f\x94\x67\x30\x83\x08" "\xfe\xff\xe9\x92\x86\x65\x73\x1c\x6d\x6a\x8f\x94\x67\x30\x83\x08", "\xca\xfe\xba\xbe\xfa\xce\xdb\xad\xde\xca\xf8\x88", 12, "\xfe\xed\xfa\xce\xde\xad\xbe\xef\xfe\xed\xfa\xce\xde\xad\xbe\xef" "\xab\xad\xda\xd2", 20, "\xd9\x31\x32\x25\xf8\x84\x06\xe5\xa5\x59\x09\xc5\xaf\xf5\x26\x9a" "\x86\xa7\xa9\x53\x15\x34\xf7\xda\x2e\x4c\x30\x3d\x8a\x31\x8a\x72" "\x1c\x3c\x0c\x95\x95\x68\x09\x53\x2f\xcf\x0e\x24\x49\xa6\xb5\x25" "\xb1\x6a\xed\xf5\xaa\x0d\xe6\x57\xba\x63\x7b\x39", 60, "\x52\x2d\xc1\xf0\x99\x56\x7d\x07\xf4\x7f\x37\xa3\x2a\x84\x42\x7d" "\x64\x3a\x8c\xdc\xbf\xe5\xc0\xc9\x75\x98\xa2\xbd\x25\x55\xd1\xaa" "\x8c\xb0\x8e\x48\x59\x0d\xbb\x3d\xa7\xb0\x8b\x10\x56\x82\x88\x38" "\xc5\xf6\x1e\x63\x93\xba\x7a\x0a\xbc\xc9\xf6\x62", "\x76\xfc\x6e\xce\x0f\x4e\x17\x68\xcd\xdf\x88\x53\xbb\x2d\x55\x1b" }, /* Test vectors for overflowing CTR. */ /* After setiv, ctr_low: 0xffffffff */ { GCRY_CIPHER_AES256, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x86\xdd\x40\xe7", 16, "", 0, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 288, "\x7d\x6e\x38\xfd\xd0\x04\x9d\x28\xdf\x4a\x10\x3f\xa3\x9e\xf8\xf8" "\x6c\x2c\x10\xa7\x91\xab\xc0\x86\xd4\x6d\x69\xea\x58\xc4\xf9\xc0" "\xd4\xee\xc2\xb0\x9d\x36\xae\xe7\xc9\xa9\x1f\x71\xa8\xee\xa2\x1d" "\x20\xfd\x79\xc7\xd9\xc4\x90\x51\x38\x97\xb6\x9f\x55\xea\xf3\xf0" "\x78\xb4\xd3\x8c\xa9\x9b\x32\x7d\x19\x36\x96\xbc\x8e\xab\x80\x9f" "\x61\x56\xcc\xbd\x3a\x80\xc6\x69\x37\x0a\x89\x89\x21\x82\xb7\x79" "\x6d\xe9\xb4\x34\xc4\x31\xe0\xbe\x71\xad\xf3\x50\x05\xb2\x61\xab" "\xb3\x1a\x80\x57\xcf\xe1\x11\x26\xcb\xa9\xd1\xf6\x58\x46\xf1\x69" "\xa2\xb8\x42\x3c\xe8\x28\x13\xca\x58\xd9\x28\x99\xf8\xc8\x17\x32" "\x4a\xf9\xb3\x4c\x7a\x47\xad\xe4\x77\x64\xec\x70\xa1\x01\x0b\x88" "\xe7\x30\x0b\xbd\x66\x25\x39\x1e\x51\x67\xee\xec\xdf\xb8\x24\x5d" "\x7f\xcb\xee\x7a\x4e\xa9\x93\xf0\xa1\x84\x7b\xfe\x5a\xe3\x86\xb2" "\xfb\xcd\x39\xe7\x1e\x5e\x48\x65\x4b\x50\x2b\x4a\x99\x46\x3f\x6f" "\xdb\xd9\x97\xdb\xe5\x6d\xa4\xdd\x6c\x18\x64\x5e\xae\x7e\x2c\xd3" "\xb4\xf3\x57\x5c\xb5\xf8\x7f\xe5\x87\xb5\x35\xdb\x80\x38\x6e\x2c" "\x5c\xdd\xeb\x7c\x63\xac\xe4\xb5\x5a\x6a\x40\x6d\x72\x69\x9a\xa9" "\x8f\x5e\x93\x91\x4d\xce\xeb\x87\xf5\x25\xed\x75\x6b\x3b\x1a\xf2" "\x0c\xd2\xa4\x10\x45\xd2\x87\xae\x29\x6d\xeb\xea\x66\x5f\xa0\xc2", "\x8c\x22\xe3\xda\x9d\x94\x8a\xbe\x8a\xbc\x55\x2c\x94\x63\x44\x40" }, /* After setiv, ctr_low: 0xfffffffe */ { GCRY_CIPHER_AES256, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x8d\xd1\xc1\xdf", 16, "", 0, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 288, "\xac\x6a\x10\x3f\xe2\x8d\xed\x27\x55\x14\xca\x1f\x03\x67\x0a\xa8" "\xa1\x07\xbf\x00\x73\x5b\x64\xef\xac\x30\x83\x81\x48\x4c\xaa\xd5" "\xff\xca\xef\x2f\x77\xbe\xfe\x1b\x20\x5c\x86\x19\xc7\xf9\x11\x99" "\x27\xc5\x57\xa7\x0a\xc2\xa8\x05\xd9\x07\x2b\xb9\x38\xa4\xef\x58" "\x92\x74\xcf\x89\xc7\xba\xfc\xb9\x70\xac\x86\xe2\x31\xba\x7c\xf9" "\xc4\xe2\xe0\x4c\x1b\xe4\x3f\x75\x83\x5c\x40\x0e\xa4\x13\x8b\x04" "\x60\x78\x57\x29\xbb\xe6\x61\x93\xe3\x16\xf9\x58\x07\x75\xd0\x96" "\xfb\x8f\x6d\x1e\x49\x0f\xd5\x31\x9e\xee\x31\xe6\x0a\x85\x93\x49" "\x22\xcf\xd6\x1b\x40\x44\x63\x9c\x95\xaf\xf0\x44\x23\x51\x37\x92" "\x0d\xa0\x22\x37\xb9\x6d\x13\xf9\x78\xba\x27\x27\xed\x08\x7e\x35" "\xe4\xe2\x28\xeb\x0e\xbe\x3d\xce\x89\x93\x35\x84\x0f\xa0\xf9\x8d" "\x94\xe9\x5a\xec\xd4\x0d\x1f\x5c\xbe\x6f\x8e\x6a\x4d\x10\x65\xbb" "\xc7\x0b\xa0\xd5\x5c\x20\x80\x0b\x4a\x43\xa6\xe1\xb0\xe0\x56\x6a" "\xde\x90\xe0\x6a\x45\xe7\xc2\xd2\x69\x9b\xc6\x62\x11\xe3\x2b\xa5" "\x45\x98\xb0\x80\xd3\x57\x4d\x1f\x09\x83\x58\xd4\x4d\xa6\xc5\x95" "\x87\x59\xb0\x58\x6c\x81\x49\xc5\x95\x18\x23\x1b\x6f\x10\x86\xa2" "\xd9\x56\x19\x30\xec\xd3\x4a\x4b\xe8\x1c\x11\x37\xfb\x31\x60\x4d" "\x4f\x9b\xc4\x95\xba\xda\x49\x43\x6c\xc7\x3d\x5b\x13\xf9\x91\xf8", "\xcd\x2b\x83\xd5\x5b\x5a\x8e\x0b\x2e\x77\x0d\x97\xbf\xf7\xaa\xab" }, /* After setiv, ctr_low: 0xfffffffd */ { GCRY_CIPHER_AES256, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x76\x8c\x18\x92", 16, "", 0, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 288, "\x3d\x6f\x4e\xf6\xd2\x6f\x4e\xce\xa6\xb4\x4a\x9e\xcb\x57\x13\x90" "\x51\x3b\xf6\xb2\x40\x55\x0c\x2c\xa2\x85\x44\x72\xf2\x90\xaf\x6b" "\x86\x8c\x75\x2a\x9c\xd6\x52\x50\xee\xc6\x5f\x59\xbc\x8d\x18\xd7" "\x87\xa5\x7f\xa0\x13\xd1\x5d\x54\x77\x30\xe2\x5d\x1b\x4f\x87\x9f" "\x3a\x41\xcb\x6a\xdf\x44\x4f\xa2\x1a\xbc\xfb\x4b\x16\x67\xed\x59" "\x65\xf0\x77\x48\xca\xfd\xf0\xb6\x90\x65\xca\x23\x09\xca\x83\x43" "\x8f\xf0\x78\xb4\x5f\x96\x2a\xfd\x29\xae\xda\x62\x85\xc5\x87\x4b" "\x2a\x3f\xba\xbe\x15\x5e\xb0\x4e\x8e\xe7\x66\xae\xb4\x80\x66\x90" "\x10\x9d\x81\xb9\x64\xd3\x36\x00\xb2\x95\xa8\x7d\xaf\x54\xf8\xbd" "\x8f\x7a\xb1\xa1\xde\x09\x0d\x10\xc8\x8e\x1e\x18\x2c\x1e\x73\x71" "\x2f\x1e\xfd\x16\x6e\xbe\xe1\x3e\xe5\xb4\xb5\xbf\x03\x63\xf4\x5a" "\x0d\xeb\xff\xe0\x61\x80\x67\x51\xb4\xa3\x1f\x18\xa5\xa9\xf1\x9a" "\xeb\x2a\x7f\x56\xb6\x01\x88\x82\x78\xdb\xec\xb7\x92\xfd\xef\x56" "\x55\xd3\x72\x35\xcd\xa4\x0d\x19\x6a\xb6\x79\x91\xd5\xcb\x0e\x3b" "\xfb\xea\xa3\x55\x9f\x77\xfb\x75\xc2\x3e\x09\x02\x73\x7a\xff\x0e" "\xa5\xf0\x83\x11\xeb\xe7\xff\x3b\xd0\xfd\x7a\x07\x53\x63\x43\x89" "\xf5\x7b\xc4\x7d\x3b\x2c\x9b\xca\x1c\xf6\xb2\xab\x13\xf5\xc4\x2a" "\xbf\x46\x77\x3b\x09\xdd\xd1\x80\xef\x55\x11\x3e\xd8\xe4\x42\x22", "\xa3\x86\xa1\x5f\xe3\x4f\x3b\xed\x12\x23\xeb\x5c\xb8\x0c\xad\x4a" }, /* After setiv, ctr_low: 0xfffffffc */ { GCRY_CIPHER_AES256, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9b\xc8\xc3\xaf", 16, "", 0, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 288, "\x33\x5f\xdc\x8d\x5d\x77\x7b\x78\xc1\x5b\x7b\xb3\xd9\x08\x9a\x0c" "\xce\x63\x4e\xef\x19\xf8\x8c\x7a\xcb\x31\x39\x93\x69\x7a\x2c\x97" "\x3a\xb4\x52\x45\x9e\x7b\x78\xbc\xa9\xad\x54\x7f\x88\xa6\xae\xd5" "\xc0\x8b\x7a\xe4\x23\x6b\xb2\x29\x98\xea\x25\x7a\xae\x11\x0c\xc9" "\xf3\x77\xa1\x74\x82\xde\x0c\xec\x68\xce\x94\xfd\xb0\xa0\xc5\x32" "\xd6\xbb\xc3\xe7\xed\x3c\x6f\x0b\x53\x9d\xf3\xc8\xeb\x4e\xee\x99" "\x19\xc7\x16\xd1\xa5\x59\x1d\xa9\xd3\xe6\x43\x52\x74\x61\x28\xe6" "\xac\xd8\x47\x63\xc2\xb7\x53\x39\xc1\x9a\xb0\xa3\xa4\x26\x14\xd0" "\x88\xa9\x8c\xc5\x6d\xe9\x21\x7c\xb9\xa5\xab\x67\xe3\x8d\xe9\x1d" "\xe3\x1c\x7b\xcd\xa4\x12\x0c\xd7\xa6\x5d\x41\xcf\xdd\x3d\xfc\xbc" "\x2a\xbb\xa2\x7a\x9c\x4b\x3a\x42\x6c\x98\x1d\x50\x99\x9c\xfb\xda" "\x21\x09\x2a\x31\xff\x05\xeb\xa5\xf1\xba\x65\x78\xbe\x15\x8e\x84" "\x35\xdd\x45\x29\xcc\xcd\x32\x2d\x27\xe9\xa8\x94\x4b\x16\x16\xcc" "\xab\xf2\xec\xfb\xa0\xb5\x9d\x39\x81\x3e\xec\x5e\x3d\x13\xd1\x83" "\x04\x79\x2d\xbb\x2c\x76\x76\x93\x28\x77\x27\x13\xdd\x1d\x3e\x89" "\x3e\x37\x46\x4c\xb8\x34\xbe\xbf\x9f\x4f\x9f\x37\xff\x0c\xe6\x14" "\x14\x66\x52\x41\x18\xa9\x39\x2b\x0c\xe5\x44\x04\xb0\x93\x06\x64" "\x67\xf7\xa0\x19\xa7\x61\xcf\x03\x7b\xcb\xc8\xb3\x88\x28\xe4\xe7", "\xe6\xe8\x0a\xe3\x72\xfc\xe0\x07\x69\x09\xf2\xeb\xbc\xc8\x6a\xf0" }, /* After setiv, ctr_low: 0xfffffffb */ { GCRY_CIPHER_AES256, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x60\x95\x1a\xe2", 16, "", 0, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 288, "\xd8\x32\x5a\xe3\x55\x8e\xb3\xc2\x51\x84\x2b\x09\x01\x5e\x6c\xfb" "\x4a\xc4\x88\xa0\x33\xe7\x3e\xbf\xe5\x7c\xd2\x00\x4c\x1a\x85\x32" "\x34\xec\x38\x9d\x18\x5f\xf1\x50\x61\x82\xee\xf3\x84\x5a\x84\x4e" "\xeb\x29\x08\x4c\x7b\xb5\x27\xec\x7d\x79\x77\xd7\xa1\x68\x91\x32" "\x2d\xf3\x38\xa9\xd6\x27\x16\xfb\x7d\x8b\x09\x5e\xcf\x1b\x74\x6d" "\xcf\x51\x91\x91\xa1\xe7\x40\x19\x43\x7b\x0d\xa5\xa9\xa5\xf4\x2e" "\x7f\x1c\xc7\xba\xa2\xea\x00\xdd\x24\x01\xa8\x66\x1e\x88\xf1\xf6" "\x0c\x9a\xd6\x2b\xda\x3f\x3e\xb2\x98\xea\x89\xc7\xc6\x63\x27\xb7" "\x6a\x48\x9a\xee\x1e\x70\xa0\xc8\xec\x3d\xc3\x3e\xb5\xf0\xc2\xb1" "\xb9\x71\x1a\x69\x9d\xdd\x72\x1e\xfe\x72\xa0\x21\xb8\x9f\x18\x96" "\x26\xcf\x89\x2e\x92\xf1\x02\x65\xa5\xb4\x2e\xb7\x4e\x12\xbd\xa0" "\x48\xbe\xf6\x5c\xef\x7e\xf3\x0a\xcf\x9d\x1f\x1e\x14\x70\x3e\xa0" "\x01\x0f\x14\xbf\x38\x10\x3a\x3f\x3f\xc2\x76\xe0\xb0\xe0\x7c\xc6" "\x77\x6d\x7f\x69\x8e\xa0\x4b\x00\xc3\x9d\xf9\x0b\x7f\x8a\x8e\xd3" "\x17\x58\x40\xfe\xaf\xf4\x16\x3a\x65\xff\xce\x85\xbb\x80\xfa\xb8" "\x34\xc9\xef\x3a\xdd\x04\x46\xca\x8f\x70\x48\xbc\x1c\x71\x4d\x6a" "\x17\x30\x32\x87\x2e\x2e\x54\x9e\x3f\x15\xed\x17\xd7\xa1\xcf\x6c" "\x5d\x0f\x3c\xee\xf5\x96\xf1\x8f\x68\x1c\xbc\x27\xdc\x10\x3c\x3c", "\x8c\x31\x06\xbb\xf8\x18\x2d\x9d\xd1\x0d\x03\x56\x2b\x28\x25\x9b" }, /* After setiv, ctr_low: 0xfffffffa */ { GCRY_CIPHER_AES256, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x6b\x99\x9b\xda", 16, "", 0, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 288, "\x7a\x74\x57\xe7\xc1\xb8\x7e\xcf\x91\x98\xf4\x1a\xa4\xdb\x4d\x2c" "\x6e\xdc\x05\x0b\xd1\x16\xdf\x25\xa8\x1e\x42\xa6\xf9\x09\x36\xfb" "\x02\x8a\x10\x7d\xa1\x07\x88\x40\xb7\x41\xfd\x64\xf6\xe3\x92\x20" "\xfd\xc9\xde\xbd\x88\x46\xd3\x1f\x20\x14\x73\x86\x09\xb6\x68\x61" "\x64\x90\xda\x24\xa8\x0f\x6a\x10\xc5\x01\xbf\x52\x8a\xee\x23\x44" "\xd5\xb0\xd8\x68\x5e\x77\xc3\x62\xed\xcb\x3c\x1b\x0c\x1f\x13\x92" "\x2c\x74\x6d\xee\x40\x1b\x6b\xfe\xbe\x3c\xb8\x02\xdd\x24\x9d\xd3" "\x3d\x4e\xd3\x9b\x18\xfd\xd6\x8f\x95\xef\xa3\xbf\xa9\x2f\x33\xa8" "\xc2\x37\x69\x58\x92\x42\x3a\x30\x46\x12\x1b\x2c\x04\xf0\xbf\xa9" "\x79\x55\xcd\xac\x45\x36\x79\xc0\xb4\xb2\x5f\x82\x88\x49\xe8\xa3" "\xbf\x33\x41\x7a\xcb\xc4\x11\x0e\xcc\x61\xed\xd1\x6b\x59\x5f\x9d" "\x20\x6f\x85\x01\xd0\x16\x2a\x51\x1b\x79\x35\x42\x5e\x49\xdf\x6f" "\x64\x68\x31\xac\x49\x34\xfb\x2b\xbd\xb1\xd9\x12\x4e\x4b\x16\xc5" "\xa6\xfe\x15\xd3\xaf\xac\x51\x08\x95\x1f\x8c\xd2\x52\x37\x8b\x88" "\xf3\x20\xe2\xf7\x09\x55\x82\x83\x1c\x38\x5f\x17\xfc\x37\x26\x21" "\xb8\xf1\xfe\xa9\xac\x54\x1e\x53\x83\x53\x3f\x43\xe4\x67\x22\xd5" "\x86\xec\xf2\xb6\x4a\x8b\x8a\x66\xea\xe0\x92\x50\x3b\x51\xe4\x00" "\x25\x2a\x7a\x64\x14\xd6\x09\xe1\x6c\x75\x32\x28\x53\x5e\xb3\xab", "\x5d\x4b\xb2\x8f\xfe\xa5\x7f\x01\x6d\x78\x6c\x13\x58\x08\xe4\x94" }, /* After setiv, ctr_low: 0xfffffff9 */ { GCRY_CIPHER_AES256, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x90\xc4\x42\x97", 16, "", 0, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 288, "\xf5\xc1\xed\xb8\x7f\x55\x7b\xb5\x47\xed\xaa\x42\xd2\xda\x33\x41" "\x4a\xe0\x36\x6d\x51\x28\x40\x9c\x35\xfb\x11\x65\x18\x83\x9c\xb5" "\x02\xb2\xa7\xe5\x52\x27\xa4\xe8\x57\x3d\xb3\xf5\xea\xcb\x21\x07" "\x67\xbe\xbe\x0f\xf6\xaa\x32\xa1\x4b\x5e\x79\x4f\x50\x67\xcd\x80" "\xfc\xf1\x65\xf2\x6c\xd0\xdb\x17\xcc\xf9\x52\x93\xfd\x5e\xa6\xb9" "\x5c\x9f\xa8\xc6\x36\xb7\x80\x80\x6a\xea\x62\xdc\x61\x13\x45\xbe" "\xab\x8f\xd8\x99\x17\x51\x9b\x29\x04\x6e\xdb\x3e\x9f\x83\xc6\x35" "\xb3\x90\xce\xcc\x74\xec\xcb\x04\x41\xac\xb1\x92\xde\x20\xb1\x67" "\xb0\x38\x14\xaa\x7d\xee\x3c\xb2\xd3\xbb\x2f\x88\x0b\x73\xcf\x7b" "\x69\xc1\x55\x5b\x2b\xf2\xd4\x38\x2b\x3c\xef\x04\xc9\x14\x7c\x31" "\xd6\x61\x88\xa8\xb3\x8c\x69\xb4\xbc\xaa\x0d\x15\xd2\xd5\x27\x63" "\xc4\xa4\x80\xe9\x2b\xe9\xd2\x34\xc9\x0e\x3f\x7b\xd3\x43\x0d\x47" "\x5d\x37\x8e\x42\xa4\x4e\xef\xcd\xbb\x3a\x5b\xa4\xe1\xb0\x8d\x64" "\xb7\x0b\x58\x52\xec\x55\xd0\xef\x23\xfe\xf2\x8d\xe0\xd1\x6a\x2c" "\xaa\x1c\x03\xc7\x3e\x58\x4c\x61\x72\x07\xc6\xfd\x0e\xbc\xd4\x6b" "\x99\x4f\x91\xda\xff\x6f\xea\x81\x0c\x76\x85\x5d\x0c\x7f\x1c\xb8" "\x84\x8c\x2f\xe1\x36\x3e\x68\xa0\x57\xf5\xdf\x13\x0a\xd6\xe1\xcd" "\xae\x23\x99\x4e\xed\x7a\x72\x1b\x7c\xe5\x65\xd1\xb7\xcf\x2f\x73", "\x1e\x2f\xcf\x3c\x95\x9a\x29\xec\xd3\x37\x90\x8c\x84\x8a\xfb\x95" }, /* After setiv, ctr_low: 0xfffffff8 */ { GCRY_CIPHER_AES256, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb7\xfa\xc7\x4f", 16, "", 0, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 288, "\x14\x33\xc6\x9d\x04\xd3\x48\x29\x0c\x6a\x24\x27\xdf\x5f\x0a\xd2" "\x71\xd6\xd0\x18\x04\xc0\x9f\x72\x0a\x60\xb7\x10\x52\x56\xf7\xae" "\x64\xb0\x28\xd4\xfd\x25\x93\x8e\x67\x7e\xac\xc2\x93\xc7\x54\x2e" "\x82\x93\x88\x6a\xb9\x8b\x73\xbc\x88\xec\x27\xdd\x4f\x9b\x21\x9e" "\x77\x98\x70\x0b\xf4\xd8\x55\xfe\xf4\xc3\x3a\xcb\xca\x3a\xfb\xd4" "\x52\x72\x2f\xf8\xac\xa9\x6a\xf5\x13\xab\x7a\x2e\x9f\x52\x41\xbd" "\x87\x90\x68\xad\x17\xbd\x5a\xff\xc3\xc6\x10\x4d\xc1\xfe\xfc\x72" "\x21\xb5\x53\x4a\x3f\xe0\x15\x9f\x29\x36\x23\xc0\x9a\x31\xb2\x0f" "\xcd\x2f\xa6\xd0\xfc\xe6\x4d\xed\x68\xb3\x3d\x26\x67\xab\x40\xf0" "\xab\xcf\x72\xc0\x50\xb1\x1e\x86\x38\xe2\xe0\x46\x3a\x2e\x3e\x1d" "\x07\xd6\x9d\xe8\xfc\xa3\xe7\xac\xc9\xa0\xb3\x22\x05\xbc\xbf\xd2" "\x63\x44\x66\xfc\xb4\x7b\xb4\x70\x7e\x96\xa9\x16\x1b\xb2\x7d\x93" "\x44\x92\x5e\xbd\x16\x34\xa7\x11\xd0\xdf\x52\xad\x6f\xbd\x23\x3c" "\x3d\x58\x16\xaf\x99\x8b\xbb\xa0\xdc\x3a\xff\x17\xda\x56\xba\x77" "\xae\xc4\xb1\x51\xe2\x61\x4f\xf0\x66\x1b\x4c\xac\x79\x34\x1c\xfd" "\x6c\x5f\x9a\x2c\x60\xfc\x47\x00\x5f\x2d\x81\xcc\xa9\xdd\x2b\xf4" "\x5b\x53\x44\x61\xd4\x13\x5a\xf3\x93\xf0\xc9\x24\xd4\xe6\x60\x6f" "\x78\x02\x0c\x75\x9d\x0d\x23\x97\x35\xe2\x06\x8a\x49\x5e\xe5\xbe", "\x23\xc0\x4a\x2f\x98\x93\xca\xbd\x2e\x44\xde\x05\xcc\xe7\xf1\xf5" }, /* After setiv, ctr_low: 0xfffffff7 */ { GCRY_CIPHER_AES256, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x4c\xa7\x1e\x02", 16, "", 0, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 288, "\x51\x51\x64\x89\xeb\x9f\xf9\xd6\xb1\xa6\x73\x5f\xf1\x62\xb5\xe4" "\x00\x80\xdb\x4c\x1c\xce\xe5\x00\xeb\xea\x6c\x57\xe4\x27\xfc\x71" "\x08\x8c\xa1\xfc\x59\x1d\x07\x45\x3c\xc9\x4e\x0f\xb6\xea\x96\x90" "\xae\xf7\x81\x1e\x7e\x6c\x5e\x50\xaf\x34\x3e\xa0\x55\x59\x8e\xe7" "\xc1\xba\x48\xfa\x9e\x07\xf6\x6a\x24\x54\x3e\x9b\xa5\xfe\x31\x16" "\x3d\x4d\x9c\xc4\xe1\xec\x26\xa0\x8b\x59\xa6\xf3\x94\xf8\x88\xda" "\x1f\x88\x23\x5f\xfb\xfd\x79\xa2\xd3\x62\x30\x66\x69\xd9\x0d\x05" "\xc0\x75\x4c\xb8\x48\x34\x1d\x97\xcf\x29\x6a\x12\x1c\x26\x54\x1d" "\x80\xa9\x06\x74\x86\xff\xc6\xb4\x72\xee\x34\xe2\x56\x06\x6c\xf5" "\x11\xe7\x26\x71\x47\x6b\x05\xbd\xe4\x0b\x40\x78\x84\x3c\xf9\xf2" "\x78\x34\x2b\x3c\x5f\x0e\x4c\xfb\x17\x39\xdc\x59\x6b\xd1\x56\xac" "\xe4\x1f\xb9\x19\xbc\xec\xb1\xd0\x6d\x47\x3b\x37\x4d\x0d\x6b\x65" "\x7c\x70\xe9\xec\x58\xcc\x09\xd4\xd9\xbf\x9f\xe0\x6c\x7f\x60\x28" "\xd8\xdf\x8e\xd1\x6a\x73\x42\xf3\x50\x01\x79\x68\x41\xc3\xba\x19" "\x1e\x2d\x30\xc2\x81\x2c\x9f\x11\x8b\xd0\xdc\x31\x3b\x01\xfe\x53" "\xa5\x11\x13\x22\x89\x40\xb9\x1b\x12\x89\xef\x9a\xcb\xa8\x03\x4f" "\x54\x1a\x15\x6d\x11\xba\x05\x09\xd3\xdb\xbf\x05\x42\x3a\x5a\x27" "\x3b\x34\x5c\x58\x8a\x5c\xa4\xc2\x28\xdc\xb2\x3a\xe9\x99\x01\xd6", "\x30\xb2\xb5\x11\x8a\x3a\x8d\x70\x67\x71\x14\xde\xed\xa7\x43\xb5" }, /* After setiv, ctr_low: 0xfffffff6 */ { GCRY_CIPHER_AES256, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x47\xab\x9f\x3a", 16, "", 0, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 288, "\x05\x72\x44\xa0\x99\x11\x1d\x2c\x4b\x03\x4f\x20\x92\x88\xbe\x55" "\xee\x31\x2c\xd9\xc0\xc1\x64\x77\x79\xd7\x3e\xfa\x5a\x7d\xf0\x48" "\xf8\xc8\xfe\x81\x8f\x89\x92\xa6\xc2\x07\xdc\x9f\x3f\xb2\xc8\xf2" "\xf3\xe9\xe1\xd3\xed\x55\xb4\xab\xc3\x22\xed\x8f\x00\xde\x32\x95" "\x91\xc0\xc5\xf3\xd3\x93\xf0\xee\x56\x14\x8f\x96\xff\xd0\x6a\xbd" "\xfc\x57\xc2\xc3\x7b\xc1\x1d\x56\x48\x3f\xa6\xc7\x92\x47\xf7\x2f" "\x0b\x85\x1c\xff\x87\x29\xe1\xbb\x9b\x14\x6c\xac\x51\x0a\xc0\x7b" "\x22\x25\xb0\x48\x92\xad\x09\x09\x6e\x39\x8e\x96\x13\x05\x55\x92" "\xbd\xd7\x5d\x95\x35\xdd\x8a\x9d\x05\x59\x60\xae\xbb\xc0\x85\x92" "\x4c\x8b\xa0\x3f\xa2\x4a\xe5\x2e\xde\x85\x1a\x39\x10\x22\x11\x1b" "\xdd\xcc\x96\xf4\x93\x97\xf5\x81\x85\xf3\x33\xda\xa1\x9a\xba\xfd" "\xb8\xaf\x60\x81\x37\xf1\x02\x88\x54\x15\xeb\x21\xd1\x19\x1a\x1f" "\x28\x9f\x02\x27\xca\xce\x97\xda\xdc\xd2\x0f\xc5\x0e\x2e\xdd\x4f" "\x1d\x24\x62\xe4\x6e\x4a\xbe\x96\x95\x38\x0c\xe9\x26\x14\xf3\xf0" "\x92\xbc\x97\xdc\x38\xeb\x64\xc3\x04\xc1\xa2\x6c\xad\xbd\xf8\x03" "\xa0\xa4\x68\xaa\x9d\x1f\x09\xe6\x62\x95\xa2\x1c\x32\xef\x62\x28" "\x7e\x54\x6d\x4b\x6a\xcc\x4a\xd0\x82\x47\x46\x0d\x45\x3c\x36\x03" "\x86\x90\x44\x65\x18\xac\x19\x75\xe6\xba\xb1\x9a\xb4\x5d\x84\x9b", "\x31\x22\x2b\x11\x6e\x2b\x94\x56\x37\x9d\xc3\xa5\xde\xe7\x6e\xc9" }, /* After setiv, ctr_low: 0xfffffff5 */ { GCRY_CIPHER_AES256, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xbc\xf6\x46\x77", 16, "", 0, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 288, "\x6e\x32\xdb\x04\x32\x57\x15\x78\x0e\x4c\x70\x66\x5c\x91\x43\x0c" "\x63\x73\xb8\x86\xad\xb0\xf1\x34\x0f\x0c\x7e\xd3\x4e\xcb\xc9\xea" "\x19\x3c\xb8\x14\xd0\xab\x9e\x9b\x22\xda\x7a\x96\xa7\xf5\xa2\x99" "\x58\xe3\xd6\x72\x0f\xf5\xdf\x88\xd1\x33\xb1\xe5\x03\x72\x62\x1c" "\xa7\xf2\x67\x50\x0e\x70\xc3\x7a\x6c\x4a\x90\xba\x78\x9e\xd2\x0b" "\x29\xd4\xc8\xa7\x57\x06\xf2\xf4\x01\x4b\x30\x53\xea\xf7\xde\xbf" "\x1c\x12\x03\xcf\x9f\xcf\x80\x8b\x77\xfd\x73\x48\x79\x19\xbe\x38" "\x75\x0b\x6d\x78\x7d\x79\x05\x98\x65\x3b\x35\x8f\x68\xff\x30\x7a" "\x6e\xf7\x10\x9e\x11\x25\xc4\x95\x97\x7d\x92\x0f\xbf\x38\x95\xbd" "\x5d\x2a\xf2\x06\x2c\xd9\x5a\x80\x91\x4e\x22\x7d\x5f\x69\x85\x03" "\xa7\x5d\xda\x22\x09\x2b\x8d\x29\x67\x7c\x8c\xf6\xb6\x49\x20\x63" "\xb9\xb6\x4d\xb6\x37\xa3\x7b\x19\xa4\x28\x90\x83\x55\x3d\x4e\x18" "\xc8\x65\xbc\xd1\xe7\xb5\xcf\x65\x28\xea\x19\x11\x5c\xea\x83\x8c" "\x44\x1f\xac\xc5\xf5\x3a\x4b\x1c\x2b\xbf\x76\xd8\x98\xdb\x50\xeb" "\x64\x45\xae\xa5\x39\xb7\xc8\xdf\x5a\x73\x6d\x2d\x0f\x4a\x5a\x17" "\x37\x66\x1c\x3d\x27\xd5\xd6\x7d\xe1\x08\x7f\xba\x4d\x43\xc2\x29" "\xf7\xbe\x83\xec\xd0\x3b\x2e\x19\x9e\xf7\xbf\x1b\x16\x34\xd8\xfa" "\x32\x17\x2a\x90\x55\x93\xd5\x3e\x14\x8d\xd6\xa1\x40\x45\x09\x52", "\x89\xf2\xae\x78\x38\x8e\xf2\xd2\x52\xa8\xba\xb6\xf2\x5d\x7c\xfc" }, /* After setiv, ctr_low: 0xfffffff4 */ { GCRY_CIPHER_AES256, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x51\xb2\x9d\x4a", 16, "", 0, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 288, "\x1d\xb8\x77\xcd\xcd\xfe\xde\x07\x97\xcb\x97\x3a\x4f\xa0\xd0\xe6" "\xcc\xcf\x8b\x71\xd5\x65\x3d\xc4\x17\x52\xe7\x1d\x6a\x68\x4a\x77" "\xca\x04\x4a\xef\x8e\x7e\xce\x79\xa1\x80\x0d\x9e\xd5\xf4\xce\x66" "\x4d\x54\xb1\x09\xd1\xb6\xb0\x43\x28\xe8\x53\xe2\x24\x9c\x76\xc5" "\x4d\x22\xf3\x6e\x13\xf3\xd7\xe0\x85\xb8\x9e\x0b\x17\x22\xc0\x79" "\x2b\x72\x57\xaa\xbd\x43\xc3\xf7\xde\xce\x22\x41\x3c\x7e\x37\x1a" "\x55\x2e\x36\x0e\x7e\xdc\xb3\xde\xd7\x33\x36\xc9\xc8\x56\x93\x51" "\x68\x77\x9a\xb0\x08\x5c\x22\x35\xef\x5c\x9b\xbf\x3e\x20\x8a\x84" "\x3d\xb3\x60\x10\xe1\x97\x30\xd7\xb3\x6f\x40\x5a\x2c\xe0\xe5\x52" "\x19\xb6\x2b\xed\x6e\x8e\x18\xb4\x8d\x78\xbd\xc4\x9f\x4f\xbd\x82" "\x98\xd6\x71\x3d\x71\x5b\x78\x73\xee\x8e\x4b\x37\x88\x9e\x21\xca" "\x00\x6c\xc2\x96\x8d\xf0\xcd\x09\x58\x54\x5a\x58\x59\x8e\x9b\xf8" "\x72\x93\xd7\xa0\xf9\xc4\xdc\x48\x89\xaa\x31\x95\xda\x4e\x2f\x79" "\x1e\x37\x49\x92\x2e\x32\x2e\x76\x54\x2a\x64\xa8\x96\x67\xe9\x75" "\x10\xa6\xeb\xad\xc6\xa8\xec\xb7\x18\x0a\x32\x26\x8d\x6e\x03\x74" "\x0e\x1f\xfc\xde\x76\xff\x6e\x96\x42\x2d\x80\x0a\xc6\x78\x70\xc4" "\xd8\x56\x7b\xa6\x38\x2f\xf6\xc0\x9b\xd7\x21\x6e\x88\x5d\xc8\xe5" "\x02\x6a\x09\x1e\xb3\x46\x44\x80\x82\x5b\xd1\x66\x06\x61\x4f\xb8", "\x16\x0e\x73\xa3\x14\x43\xdb\x15\x9c\xb0\x0d\x30\x6d\x9b\xe1\xb1" }, /* After setiv, ctr_low: 0xfffffff3 */ { GCRY_CIPHER_AES256, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xaa\xef\x44\x07", 16, "", 0, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 288, "\x42\x71\x54\xe2\xdb\x50\x5d\x3c\x10\xbd\xf8\x60\xbd\xdb\x26\x14" "\x7d\x13\x59\x98\x28\xfb\x43\x42\xca\x72\xe6\xd8\x58\x00\xa2\x1b" "\x6a\x61\xb4\x3a\x80\x6b\x9e\x14\xbd\x11\x33\xab\xe9\xb9\x91\x95" "\xd7\x5d\xc3\x98\x1f\x7f\xcb\xa8\xf0\xec\x31\x26\x51\xea\x2e\xdf" "\xd9\xde\x70\xf5\x84\x27\x3a\xac\x22\x05\xb9\xce\x2a\xfb\x2a\x83" "\x1e\xce\x0e\xb2\x31\x35\xc6\xe6\xc0\xd7\xb0\x5f\xf5\xca\xdb\x13" "\xa7\xfe\x4f\x85\xa3\x4f\x94\x5c\xc1\x04\x12\xde\x6f\xa1\xdb\x41" "\x59\x82\x22\x22\x65\x97\x6d\xc8\x67\xab\xf3\x90\xeb\xa4\x00\xb3" "\x7d\x94\x3d\x7b\x2a\xe2\x85\x36\x87\x16\xb8\x19\x92\x02\xe0\x43" "\x42\x85\xa1\xe6\xb8\x11\x30\xcc\x2c\xd8\x63\x09\x0e\x53\x5f\xa3" "\xe0\xd4\xee\x0e\x04\xee\x65\x61\x96\x84\x42\x0c\x68\x8d\xb7\x48" "\xa3\x02\xb4\x82\x69\xf2\x35\xe4\xce\x3b\xe3\x44\xce\xad\x49\x32" "\xab\xda\x04\xea\x06\x60\xa6\x2a\x7d\xee\x0f\xb8\x95\x90\x22\x62" "\x9c\x78\x59\xd3\x7b\x61\x02\x65\x63\x96\x9f\x67\x50\xa0\x61\x43" "\x53\xb2\x3f\x22\xed\x8c\x42\x39\x97\xd9\xbc\x6e\x81\xb9\x21\x97" "\xc6\x5b\x68\xd7\x7f\xd0\xc5\x4a\xfb\x74\xc4\xfd\x9a\x2a\xb8\x9b" "\x48\xe0\x00\xea\x6d\xf5\x30\x26\x61\x8f\xa5\x45\x70\xc9\x3a\xea" "\x6d\x19\x11\x57\x0f\x21\xe6\x0a\x53\x94\xe3\x0c\x99\xb0\x2f\xc5", "\x92\x92\x89\xcd\x4f\x3c\x6d\xbc\xe8\xb3\x70\x14\x5b\x3c\x12\xe4" }, /* After setiv, ctr_low: 0xfffffff2 */ { GCRY_CIPHER_AES256, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa1\xe3\xc5\x3f", 16, "", 0, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 288, "\x41\xc3\xcb\xd7\x6e\xde\x2a\xc6\x15\x05\xc6\xba\x27\xae\xcd\x37" "\xc0\xe5\xbf\xb9\x5c\xdc\xd6\xad\x1a\xe1\x35\x7c\xc0\x85\x85\x51" "\x8c\x98\x06\xc0\x72\x43\x71\x7a\x2d\x7c\x81\x3c\xe7\xd6\x32\x8e" "\x22\x2b\x46\x95\x6a\xde\x45\x40\x56\xe9\x63\x32\x68\xbf\xb6\x78" "\xb7\x86\x00\x9d\x2c\x9e\xed\x67\xc1\x9b\x09\x9e\xd9\x0a\x56\xcb" "\x57\xc9\x48\x14\x23\x4e\x97\x04\xb5\x85\x25\x1d\xcb\x1a\x79\x9b" "\x54\x06\x95\xad\x16\x81\x84\x3a\x38\xec\x41\x90\x2a\xfa\x50\xe0" "\xb9\x20\xa6\xeb\xfe\x2e\x5c\xa1\xf6\x3c\x69\x4c\xce\xf8\x30\xe0" "\x87\x68\xa2\x3a\x9d\xad\x75\xd4\xa5\x6b\x0a\x90\x65\xa2\x27\x64" "\x9d\xf5\xa0\x6f\xd0\xd3\x62\xa5\x2d\xae\x02\x89\xb4\x1a\xfa\x32" "\x9b\xa0\x44\xdd\x50\xde\xaf\x41\xa9\x89\x1e\xb0\x41\xbc\x9c\x41" "\xb0\x35\x5e\xf1\x9a\xd9\xab\x57\x53\x21\xca\x39\xfc\x8b\xb4\xd4" "\xb2\x19\x8a\xe9\xb2\x24\x1e\xce\x2e\x19\xb0\xd2\x93\x30\xc4\x70" "\xe2\xf8\x6a\x8a\x99\x3b\xed\x71\x7e\x9e\x98\x99\x2a\xc6\xdd\xcf" "\x43\x32\xdb\xfb\x27\x22\x89\xa4\xc5\xe0\xa2\x94\xe9\xcf\x9d\x48" "\xab\x3f\xfa\x4f\x75\x63\x46\xdd\xfe\xfa\xf0\xbf\x6e\xa1\xf9\xca" "\xb1\x77\x79\x35\x6c\x33\xe1\x57\x68\x50\xe9\x78\x4e\xe4\xe2\xf0" "\xcf\xe4\x23\xde\xf4\xa7\x34\xb3\x44\x97\x38\xd2\xbd\x27\x44\x0e", "\x75\x0a\x41\x3b\x87\xe3\xc7\xf6\xd6\xe3\xab\xfa\x4b\xbe\x2e\x56" }, /* After setiv, ctr_low: 0xfffffff1 */ { GCRY_CIPHER_AES256, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x5a\xbe\x1c\x72", 16, "", 0, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 288, "\xf1\x3c\x7a\xa4\xa9\xaf\xe7\x49\x19\x7d\xad\x50\xc1\x6a\x84\x87" "\xf5\x69\xe4\xe5\xc2\x0a\x90\x33\xc3\xeb\x76\x63\x5f\x9b\x1d\xf9" "\x53\x4a\x2a\x6d\x6b\x61\xe0\x5d\xed\xcb\x98\x0d\xf2\x57\x33\x12" "\xd1\x44\xaa\x7a\x7e\x4e\x41\x0e\xe6\xa7\x9f\x17\x92\x28\x91\xad" "\xca\xce\xf2\xa8\x73\x4a\xad\x89\x62\x73\x0b\x9a\x68\x91\xa8\x11" "\x44\x01\xfd\x57\xe4\xf8\x84\x55\x2b\x66\xdb\xb9\xd6\xee\x83\xe5" "\x57\xea\x5c\x6a\x23\x87\xdd\x0a\x45\x63\xb4\x0c\x8f\xc5\x9f\x22" "\xf3\x4f\x4e\x6f\x7b\x14\x62\xf7\x80\x59\x4a\xc5\xc8\xae\x8a\x6f" "\x5e\xe3\x1e\xe6\xae\xec\x99\x77\x6b\x88\x14\xe3\x58\x88\x61\x74" "\x38\x91\xa1\x32\xb8\xd2\x39\x6b\xe2\xcb\x8e\x77\xde\x92\x36\x78" "\xad\x50\xcf\x08\xb8\xfa\x29\x59\xb4\x68\x1b\x23\x10\x57\x32\x92" "\xf8\xec\xe1\x97\xdb\x30\x85\x22\xb5\x68\x2f\xf2\x98\xda\x06\xee" "\x65\x02\xe7\xf9\xc8\xc1\xca\x8f\xd3\xed\x4a\x3c\x09\xdd\xde\x64" "\xd9\x85\x17\x2c\x62\x41\x35\x24\xed\x6b\x87\x78\x1e\xb5\x7a\x9b" "\xa3\x90\xa3\x99\xc7\x39\x51\x10\xb7\x6a\x12\x3b\x64\xfe\x32\x3c" "\xb6\x84\x9a\x3f\x95\xd3\xcb\x22\x69\x9c\xf9\xb7\xc2\x8b\xf4\x55" "\x68\x60\x11\x20\xc5\x3e\x0a\xc0\xba\x00\x0e\x88\x96\x66\xfa\xf0" "\x75\xbc\x2b\x9c\xff\xc5\x33\x7b\xaf\xb2\xa6\x34\x78\x44\x9c\xa7", "\x01\x24\x0e\x17\x17\xe5\xfc\x90\x07\xfa\x78\xd5\x5d\x66\xa3\xf5" }, }; gcry_cipher_hd_t hde, hdd; unsigned char out[MAX_GCM_DATA_LEN]; unsigned char tag[GCRY_GCM_BLOCK_LEN]; int i, keylen; gcry_error_t err = 0; size_t pos, poslen, taglen2; int byteNum; if (verbose) fprintf (stderr, " Starting GCM checks.\n"); for (i = 0; i < sizeof (tv) / sizeof (tv[0]); i++) { 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_siv_cipher (void) { static const struct tv { int algo; char key[MAX_DATA_LEN]; char ad1[MAX_DATA_LEN]; int ad1len; char ad2[MAX_DATA_LEN]; int ad2len; char nonce[MAX_DATA_LEN]; int noncelen; unsigned char plaintext[MAX_DATA_LEN]; int inlen; char tag[MAX_DATA_LEN]; char out[MAX_DATA_LEN]; } tv[] = { /* Test vectors from RFC5297 */ { GCRY_CIPHER_AES128, "\xff\xfe\xfd\xfc\xfb\xfa\xf9\xf8\xf7\xf6\xf5\xf4\xf3\xf2\xf1\xf0" "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff", "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f" "\x20\x21\x22\x23\x24\x25\x26\x27", 24, "", -1, "", -1, "\x11\x22\x33\x44\x55\x66\x77\x88\x99\xaa\xbb\xcc\xdd\xee", 14, "\x85\x63\x2d\x07\xc6\xe8\xf3\x7f\x95\x0a\xcd\x32\x0a\x2e\xcc\x93", "\x40\xc0\x2b\x96\x90\xc4\xdc\x04\xda\xef\x7f\x6a\xfe\x5c" }, { GCRY_CIPHER_AES128, "\x7f\x7e\x7d\x7c\x7b\x7a\x79\x78\x77\x76\x75\x74\x73\x72\x71\x70" "\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f", "\x00\x11\x22\x33\x44\x55\x66\x77\x88\x99\xaa\xbb\xcc\xdd\xee\xff" "\xde\xad\xda\xda\xde\xad\xda\xda\xff\xee\xdd\xcc\xbb\xaa\x99\x88" "\x77\x66\x55\x44\x33\x22\x11\x00", 40, "\x10\x20\x30\x40\x50\x60\x70\x80\x90\xa0", 10, "\x09\xf9\x11\x02\x9d\x74\xe3\x5b\xd8\x41\x56\xc5\x63\x56\x88\xc0", 16, "\x74\x68\x69\x73\x20\x69\x73\x20\x73\x6f\x6d\x65\x20\x70\x6c\x61" "\x69\x6e\x74\x65\x78\x74\x20\x74\x6f\x20\x65\x6e\x63\x72\x79\x70" "\x74\x20\x75\x73\x69\x6e\x67\x20\x53\x49\x56\x2d\x41\x45\x53", 47, "\x7b\xdb\x6e\x3b\x43\x26\x67\xeb\x06\xf4\xd1\x4b\xff\x2f\xbd\x0f", "\xcb\x90\x0f\x2f\xdd\xbe\x40\x43\x26\x60\x19\x65\xc8\x89\xbf\x17" "\xdb\xa7\x7c\xeb\x09\x4f\xa6\x63\xb7\xa3\xf7\x48\xba\x8a\xf8\x29" "\xea\x64\xad\x54\x4a\x27\x2e\x9c\x48\x5b\x62\xa3\xfd\x5c\x0d" }, /* From libaes_siv */ { GCRY_CIPHER_AES256, "\xff\xfe\xfd\xfc\xfb\xfa\xf9\xf8\xf7\xf6\xf5\xf4\xf3\xf2\xf1\xf0" "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff" "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff" "\xff\xfe\xfd\xfc\xfb\xfa\xf9\xf8\xf7\xf6\xf5\xf4\xf3\xf2\xf1\xf0", "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f" "\x20\x21\x22\x23\x24\x25\x26\x27", 24, "", -1, "", -1, "\x11\x22\x33\x44\x55\x66\x77\x88\x99\xaa\xbb\xcc\xdd\xee", 14, "\x72\x4d\xfb\x2e\xaf\x94\xdb\xb1\x9b\x0b\xa3\xa2\x99\xa0\x80\x1e", "\xf3\xb0\x5a\x55\x49\x8e\xc2\x55\x26\x90\xb8\x98\x10\xe4" }, /* From https://github.com/cryptomator/siv-mode */ { GCRY_CIPHER_AES128, "\x90\xe5\x90\xae\xca\x19\x70\xed\xd1\x9f\xe5\x0f\xa6\x91\xae\x12" "\x34\x2c\x49\x7a\x22\xc2\x4f\xaa\x9e\x87\x19\x2e\x34\x00\xfb\xce", "\x2d\xdf\x87\xac\x97\x5d\x0c", 7, "", -1, "", -1, "\x44", 1, "\x7b\x0d\xdd\x88\x74\x39\x43\xc6\x44\xc1\xd1\xa2\x18\xa3\x1e\xdf", "\x2e" }, { GCRY_CIPHER_AES128, "\xf6\xde\x98\x19\x31\x1b\xd3\xde\x0b\xd1\x98\x70\x9d\xea\x9f\xdf" "\xb8\x2e\x80\x44\xe4\x00\x13\x2a\x90\xff\xe9\xa9\xde\x81\x44\x75", "\x7b\xd3\x6f\x24\x09\xfc\xd0\x0f\x5c\xcd\x9a\xf2\xe3\xf5\x76\x45" "\xf7\xc5\x3f\x39\xf7\xad\xcb\xf0\x7a\x0e\x43\x30\x7e\x55\xa2\x53" "\x47\x49\x48\x20\x20\x27\x6c\x8a\x20\x44\x22\xcd\x26\xbf\x7e\x89" "\x88\x38\x0d\x94\xff\x12\xc5\x18\xfd\x20\x2c\x2a\x1b\x00\xb3", 63, "", -1, "", -1, "", 0, "\x4c\x0e\xc2\xcc\x61\x59\xb1\x17\xdb\x98\x6d\x9a\xa5\xb4\xa0\x11", "" }, /* From https://github.com/RustCrypto/AEADs */ { GCRY_CIPHER_AES128, "\xff\xfe\xfd\xfc\xfb\xfa\xf9\xf8\xf7\xf6\xf5\xf4\xf3\xf2\xf1\xf0" "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff", "", -1, "", -1, "", -1, "", 0, "\xf2\x00\x7a\x5b\xeb\x2b\x89\x00\xc5\x88\xa7\xad\xf5\x99\xf1\x72", "" }, { GCRY_CIPHER_AES128, "\xff\xfe\xfd\xfc\xfb\xfa\xf9\xf8\xf7\xf6\xf5\xf4\xf3\xf2\xf1\xf0" "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff", "", -1, "", -1, "", -1, "\x00\x11\x22\x33\x44\x55\x66\x77\x88\x99\xaa\xbb\xcc\xdd\xee\xff", 16, "\xf3\x04\xf9\x12\x86\x3e\x30\x3d\x5b\x54\x0e\x50\x57\xc7\x01\x0c", "\x94\x2f\xfa\xf4\x5b\x0e\x5c\xa5\xfb\x9a\x56\xa5\x26\x3b\xb0\x65" }, /* From nettle */ { GCRY_CIPHER_AES128, "\xff\xfe\xfd\xfc\xfb\xfa\xf9\xf8\xf7\xf6\xf5\xf4\xf3\xf2\xf1\xf0" "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff", "", 0, "", -1, "\x01", 1, "", 0, "\xc6\x96\xf8\x4f\xdf\x92\xab\xa3\xc3\x1c\x23\xd5\xf2\x08\x75\x13", "" }, /* From botan */ { GCRY_CIPHER_AES128, "\x2a\x83\xf6\x10\xa1\xd1\x77\xec\x2e\x00\x89\x80\xdc\x02\xa6\x6e" "\xeb\x75\xaf\x6c\xba\x44\xa4\xe0\x9f\x3d\x93\xea\x1f\xa2\x88\x67", "", 0, "", -1, "", -1, "", 0, "\x6b\xc5\xca\x86\x32\x29\x66\x75\x18\xa9\xab\xbd\x5a\xe6\xc1\xd5", "" }, { GCRY_CIPHER_AES128, "\x97\xef\x57\xd4\xe2\xe9\x2f\x14\xdf\x73\x31\xfb\xa3\xd9\xf3\x58" "\x87\xdd\xe7\xad\x86\x91\xfb\x80\x17\x68\x58\xd6\x59\x20\x14\x27", "", 0, "", -1, "", -1, "\x75\x73\x97\x4d\x6f\xa7\x65\xbc\xd0\xe6\x23\x2c\x24\x0e\x82\x7e", 16, "\x68\x60\xa9\xc7\xbf\x4a\x6b\x21\x92\x44\xd7\xa8\xea\xa1\xf5\x0c", "\x6f\x97\x93\x82\xcd\xe6\x8d\xe6\x0a\xb2\xad\x09\x53\x60\x64\x85" } }; gcry_cipher_hd_t hde, hdd; unsigned char out[MAX_DATA_LEN]; unsigned char tag[16]; int i, keylen; gcry_error_t err = 0; size_t taglen2; if (verbose) fprintf (stderr, " Starting SIV checks.\n"); for (i = 0; i < sizeof (tv) / sizeof (tv[0]); i++) { 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 SIV mode for %s [%i]\n", gcry_cipher_algo_name (tv[i].algo), tv[i].algo); err = gcry_cipher_open (&hde, tv[i].algo, GCRY_CIPHER_MODE_SIV, 0); if (!err) err = gcry_cipher_open (&hdd, tv[i].algo, GCRY_CIPHER_MODE_SIV, 0); if (err) { fail ("aes-siv, gcry_cipher_open failed: %s\n", gpg_strerror (err)); return; } keylen = gcry_cipher_get_algo_keylen (tv[i].algo) * 2; if (!keylen) { fail ("aes-siv, gcry_cipher_get_algo_keylen failed\n"); return; } err = gcry_cipher_setkey (hde, tv[i].key, keylen); if (!err) err = gcry_cipher_setkey (hdd, tv[i].key, keylen); if (err) { fail ("aes-siv, gcry_cipher_setkey failed: %s\n", gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } if (tv[i].ad1len >= 0) { err = gcry_cipher_authenticate (hde, tv[i].ad1, tv[i].ad1len); if (!err) err = gcry_cipher_authenticate (hdd, tv[i].ad1, tv[i].ad1len); if (err) { fail ("aes-siv, gcry_cipher_authenticate failed: %s\n", gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } } if (tv[i].ad2len >= 0) { err = gcry_cipher_authenticate (hde, tv[i].ad2, tv[i].ad2len); if (!err) err = gcry_cipher_authenticate (hdd, tv[i].ad2, tv[i].ad2len); if (err) { fail ("aes-siv, gcry_cipher_authenticate failed: %s\n", gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } } if (tv[i].noncelen >= 0) { err = gcry_cipher_setiv (hde, tv[i].nonce, tv[i].noncelen); if (!err) err = gcry_cipher_setiv (hdd, tv[i].nonce, tv[i].noncelen); if (err) { fail ("aes-siv, gcry_cipher_setiv failed: %s\n", gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } /* Further AD not allowed after setting nonce. */ err = gcry_cipher_authenticate (hde, tv[i].nonce, tv[i].noncelen); if (!err) { fail ("aes-siv, gcry_cipher_authenticate after setiv did not fail\n"); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } } err = gcry_cipher_info (hde, GCRYCTL_GET_TAGLEN, NULL, &taglen2); if (err) { fail ("cipher-siv, gcryctl_get_taglen failed (tv %d): %s\n", i, gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } if (taglen2 != 16) { fail ("cipher-siv, gcryctl_get_taglen returned bad length" " (tv %d): got=%zu want=%d\n", i, taglen2, 16); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } if (tv[i].inlen) { err = gcry_cipher_encrypt (hde, out, tv[i].inlen, tv[i].plaintext, tv[i].inlen); if (err) { fail ("aes-siv, gcry_cipher_encrypt (%d) failed: %s\n", i, gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } if (memcmp (tv[i].out, out, tv[i].inlen)) { mismatch (tv[i].out, tv[i].inlen, out, tv[i].inlen); fail ("aes-siv, encrypt mismatch entry %d\n", i); } err = gcry_cipher_gettag (hde, tag, taglen2); if (err) { fail ("aes-siv, gcry_cipher_gettag(%d) failed: %s\n", i, gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } if (memcmp (tv[i].tag, tag, taglen2)) { mismatch (tv[i].tag, taglen2, tag, taglen2); fail ("aes-siv, tag mismatch entry %d\n", i); } err = gcry_cipher_set_decryption_tag (hdd, tag, taglen2); if (err) { fail ("aes-siv, gcry_cipher_set_decryption_tag (%d) failed: %s\n", i, gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } err = gcry_cipher_decrypt (hdd, out, tv[i].inlen, NULL, 0); if (err) { fail ("aes-siv, gcry_cipher_decrypt (%d) failed: %s\n", i, gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } if (memcmp (tv[i].plaintext, out, tv[i].inlen)) fail ("aes-siv, decrypt mismatch entry %d\n", i); err = gcry_cipher_checktag (hdd, tag, taglen2); if (err) { fail ("aes-siv, gcry_cipher_checktag (%d) failed: %s\n", i, gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } } else { err = gcry_cipher_gettag (hde, tag, taglen2); if (err) { fail ("aes-siv, gcry_cipher_gettag(%d) failed: %s\n", i, gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } if (memcmp (tv[i].tag, tag, taglen2)) { mismatch (tv[i].tag, taglen2, tag, taglen2); fail ("aes-siv, tag mismatch entry %d\n", i); } err = gcry_cipher_checktag (hdd, tv[i].tag, taglen2); if (err) { fail ("aes-siv, gcry_cipher_checktag (%d) failed: %s\n", i, gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } } gcry_cipher_close (hde); gcry_cipher_close (hdd); } if (verbose) fprintf (stderr, " Completed SIV checks.\n"); } static void check_gcm_siv_cipher (void) { static const struct tv { int algo; char key[MAX_DATA_LEN]; char nonce[12]; char ad[MAX_DATA_LEN]; int adlen; unsigned char plaintext[MAX_DATA_LEN]; int inlen; char out[MAX_DATA_LEN]; char tag[MAX_DATA_LEN]; } tv[] = { /* Test vectors from RFC8452 */ { GCRY_CIPHER_AES128, "\xee\x8e\x1e\xd9\xff\x25\x40\xae\x8f\x2b\xa9\xf5\x0b\xc2\xf2\x7c", "\x75\x2a\xba\xd3\xe0\xaf\xb5\xf4\x34\xdc\x43\x10", "example", 7, "Hello world", 11, "\x5d\x34\x9e\xad\x17\x5e\xf6\xb1\xde\xf6\xfd", "\x4f\xbc\xde\xb7\xe4\x79\x3f\x4a\x1d\x7e\x4f\xaa\x70\x10\x0a\xf1" }, { GCRY_CIPHER_AES128, "\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", "\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", "", -1, "", 0, "", "\xdc\x20\xe2\xd8\x3f\x25\x70\x5b\xb4\x9e\x43\x9e\xca\x56\xde\x25" }, { GCRY_CIPHER_AES128, "\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", "\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", "", 0, "", 0, "", "\xdc\x20\xe2\xd8\x3f\x25\x70\x5b\xb4\x9e\x43\x9e\xca\x56\xde\x25", }, { GCRY_CIPHER_AES128, "\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", "\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", "", 0, "\x01\x00\x00\x00\x00\x00\x00\x00", 8, "\xb5\xd8\x39\x33\x0a\xc7\xb7\x86", "\x57\x87\x82\xff\xf6\x01\x3b\x81\x5b\x28\x7c\x22\x49\x3a\x36\x4c", }, { GCRY_CIPHER_AES128, "\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", "\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", "", 0, "\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 12, "\x73\x23\xea\x61\xd0\x59\x32\x26\x00\x47\xd9\x42", "\xa4\x97\x8d\xb3\x57\x39\x1a\x0b\xc4\xfd\xec\x8b\x0d\x10\x66\x39", }, { GCRY_CIPHER_AES128, "\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", "\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", "", 0, "\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 16, "\x74\x3f\x7c\x80\x77\xab\x25\xf8\x62\x4e\x2e\x94\x85\x79\xcf\x77", "\x30\x3a\xaf\x90\xf6\xfe\x21\x19\x9c\x60\x68\x57\x74\x37\xa0\xc4", }, { GCRY_CIPHER_AES128, "\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", "\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", "", 0, "\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 32, "\x84\xe0\x7e\x62\xba\x83\xa6\x58\x54\x17\x24\x5d\x7e\xc4\x13\xa9" "\xfe\x42\x7d\x63\x15\xc0\x9b\x57\xce\x45\xf2\xe3\x93\x6a\x94\x45", "\x1a\x8e\x45\xdc\xd4\x57\x8c\x66\x7c\xd8\x68\x47\xbf\x61\x55\xff", }, { GCRY_CIPHER_AES128, "\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", "\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", "", 0, "\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 48, "\x3f\xd2\x4c\xe1\xf5\xa6\x7b\x75\xbf\x23\x51\xf1\x81\xa4\x75\xc7" "\xb8\x00\xa5\xb4\xd3\xdc\xf7\x01\x06\xb1\xee\xa8\x2f\xa1\xd6\x4d" "\xf4\x2b\xf7\x22\x61\x22\xfa\x92\xe1\x7a\x40\xee\xaa\xc1\x20\x1b", "\x5e\x6e\x31\x1d\xbf\x39\x5d\x35\xb0\xfe\x39\xc2\x71\x43\x88\xf8", }, { GCRY_CIPHER_AES128, "\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", "\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", "", 0, "\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 64, "\x24\x33\x66\x8f\x10\x58\x19\x0f\x6d\x43\xe3\x60\xf4\xf3\x5c\xd8" "\xe4\x75\x12\x7c\xfc\xa7\x02\x8e\xa8\xab\x5c\x20\xf7\xab\x2a\xf0" "\x25\x16\xa2\xbd\xcb\xc0\x8d\x52\x1b\xe3\x7f\xf2\x8c\x15\x2b\xba" "\x36\x69\x7f\x25\xb4\xcd\x16\x9c\x65\x90\xd1\xdd\x39\x56\x6d\x3f", "\x8a\x26\x3d\xd3\x17\xaa\x88\xd5\x6b\xdf\x39\x36\xdb\xa7\x5b\xb8", }, { GCRY_CIPHER_AES128, "\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", "\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", "\x01", 1, "\x02\x00\x00\x00\x00\x00\x00\x00", 8, "\x1e\x6d\xab\xa3\x56\x69\xf4\x27", "\x3b\x0a\x1a\x25\x60\x96\x9c\xdf\x79\x0d\x99\x75\x9a\xbd\x15\x08", }, { GCRY_CIPHER_AES128, "\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", "\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", "\x01", 1, "\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 12, "\x29\x6c\x78\x89\xfd\x99\xf4\x19\x17\xf4\x46\x20", "\x08\x29\x9c\x51\x02\x74\x5a\xaa\x3a\x0c\x46\x9f\xad\x9e\x07\x5a", }, { GCRY_CIPHER_AES128, "\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", "\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", "\x01", 1, "\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 16, "\xe2\xb0\xc5\xda\x79\xa9\x01\xc1\x74\x5f\x70\x05\x25\xcb\x33\x5b", "\x8f\x89\x36\xec\x03\x9e\x4e\x4b\xb9\x7e\xbd\x8c\x44\x57\x44\x1f", }, { GCRY_CIPHER_AES128, "\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", "\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", "\x01", 1, "\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 32, "\x62\x00\x48\xef\x3c\x1e\x73\xe5\x7e\x02\xbb\x85\x62\xc4\x16\xa3" "\x19\xe7\x3e\x4c\xaa\xc8\xe9\x6a\x1e\xcb\x29\x33\x14\x5a\x1d\x71", "\xe6\xaf\x6a\x7f\x87\x28\x7d\xa0\x59\xa7\x16\x84\xed\x34\x98\xe1", }, { GCRY_CIPHER_AES128, "\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", "\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", "\x01", 1, "\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 48, "\x50\xc8\x30\x3e\xa9\x39\x25\xd6\x40\x90\xd0\x7b\xd1\x09\xdf\xd9" "\x51\x5a\x5a\x33\x43\x10\x19\xc1\x7d\x93\x46\x59\x99\xa8\xb0\x05" "\x32\x01\xd7\x23\x12\x0a\x85\x62\xb8\x38\xcd\xff\x25\xbf\x9d\x1e", "\x6a\x8c\xc3\x86\x5f\x76\x89\x7c\x2e\x4b\x24\x5c\xf3\x1c\x51\xf2", }, { GCRY_CIPHER_AES128, "\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", "\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", "\x01", 1, "\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 64, "\x2f\x5c\x64\x05\x9d\xb5\x5e\xe0\xfb\x84\x7e\xd5\x13\x00\x37\x46" "\xac\xa4\xe6\x1c\x71\x1b\x5d\xe2\xe7\xa7\x7f\xfd\x02\xda\x42\xfe" "\xec\x60\x19\x10\xd3\x46\x7b\xb8\xb3\x6e\xbb\xae\xbc\xe5\xfb\xa3" "\x0d\x36\xc9\x5f\x48\xa3\xe7\x98\x0f\x0e\x7a\xc2\x99\x33\x2a\x80", "\xcd\xc4\x6a\xe4\x75\x56\x3d\xe0\x37\x00\x1e\xf8\x4a\xe2\x17\x44", }, { GCRY_CIPHER_AES128, "\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", "\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", "\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 12, "\x02\x00\x00\x00", 4, "\xa8\xfe\x3e\x87", "\x07\xeb\x1f\x84\xfb\x28\xf8\xcb\x73\xde\x8e\x99\xe2\xf4\x8a\x14", }, { GCRY_CIPHER_AES128, "\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", "\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", "\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x02\x00", 18, "\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x04\x00\x00\x00", 20, "\x6b\xb0\xfe\xcf\x5d\xed\x9b\x77\xf9\x02\xc7\xd5\xda\x23\x6a\x43" "\x91\xdd\x02\x97", "\x24\xaf\xc9\x80\x5e\x97\x6f\x45\x1e\x6d\x87\xf6\xfe\x10\x65\x14", }, { GCRY_CIPHER_AES128, "\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", "\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", "\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x02\x00\x00\x00", 20, "\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x04\x00", 18, "\x44\xd0\xaa\xf6\xfb\x2f\x1f\x34\xad\xd5\xe8\x06\x4e\x83\xe1\x2a" "\x2a\xda", "\xbf\xf9\xb2\xef\x00\xfb\x47\x92\x0c\xc7\x2a\x0c\x0f\x13\xb9\xfd", }, { GCRY_CIPHER_AES128, "\xe6\x60\x21\xd5\xeb\x8e\x4f\x40\x66\xd4\xad\xb9\xc3\x35\x60\xe4", "\xf4\x6e\x44\xbb\x3d\xa0\x01\x5c\x94\xf7\x08\x87", "", 0, "", 0, "", "\xa4\x19\x4b\x79\x07\x1b\x01\xa8\x7d\x65\xf7\x06\xe3\x94\x95\x78", }, { GCRY_CIPHER_AES128, "\x36\x86\x42\x00\xe0\xea\xf5\x28\x4d\x88\x4a\x0e\x77\xd3\x16\x46", "\xba\xe8\xe3\x7f\xc8\x34\x41\xb1\x60\x34\x56\x6b", "\x46\xbb\x91\xc3\xc5", 5, "\x7a\x80\x6c", 3, "\xaf\x60\xeb", "\x71\x1b\xd8\x5b\xc1\xe4\xd3\xe0\xa4\x62\xe0\x74\xee\xa4\x28\xa8", }, { GCRY_CIPHER_AES128, "\xae\xdb\x64\xa6\xc5\x90\xbc\x84\xd1\xa5\xe2\x69\xe4\xb4\x78\x01", "\xaf\xc0\x57\x7e\x34\x69\x9b\x9e\x67\x1f\xdd\x4f", "\xfc\x88\x0c\x94\xa9\x51\x98\x87\x42\x96", 10, "\xbd\xc6\x6f\x14\x65\x45", 6, "\xbb\x93\xa3\xe3\x4d\x3c", "\xd6\xa9\xc4\x55\x45\xcf\xc1\x1f\x03\xad\x74\x3d\xba\x20\xf9\x66", }, { GCRY_CIPHER_AES128, "\xd5\xcc\x1f\xd1\x61\x32\x0b\x69\x20\xce\x07\x78\x7f\x86\x74\x3b", "\x27\x5d\x1a\xb3\x2f\x6d\x1f\x04\x34\xd8\x84\x8c", "\x04\x67\x87\xf3\xea\x22\xc1\x27\xaa\xf1\x95\xd1\x89\x47\x28", 15, "\x11\x77\x44\x1f\x19\x54\x95\x86\x0f", 9, "\x4f\x37\x28\x1f\x7a\xd1\x29\x49\xd0", "\x1d\x02\xfd\x0c\xd1\x74\xc8\x4f\xc5\xda\xe2\xf6\x0f\x52\xfd\x2b", }, { GCRY_CIPHER_AES128, "\xb3\xfe\xd1\x47\x3c\x52\x8b\x84\x26\xa5\x82\x99\x59\x29\xa1\x49", "\x9e\x9a\xd8\x78\x0c\x8d\x63\xd0\xab\x41\x49\xc0", "\xc9\x88\x2e\x53\x86\xfd\x9f\x92\xec\x48\x9c\x8f\xde\x2b\xe2\xcf" "\x97\xe7\x4e\x93", 20, "\x9f\x57\x2c\x61\x4b\x47\x45\x91\x44\x74\xe7\xc7", 12, "\xf5\x46\x73\xc5\xdd\xf7\x10\xc7\x45\x64\x1c\x8b", "\xc1\xdc\x2f\x87\x1f\xb7\x56\x1d\xa1\x28\x6e\x65\x5e\x24\xb7\xb0", }, { GCRY_CIPHER_AES128, "\x2d\x4e\xd8\x7d\xa4\x41\x02\x95\x2e\xf9\x4b\x02\xb8\x05\x24\x9b", "\xac\x80\xe6\xf6\x14\x55\xbf\xac\x83\x08\xa2\xd4", "\x29\x50\xa7\x0d\x5a\x1d\xb2\x31\x6f\xd5\x68\x37\x8d\xa1\x07\xb5" "\x2b\x0d\xa5\x52\x10\xcc\x1c\x1b\x0a", 25, "\x0d\x8c\x84\x51\x17\x80\x82\x35\x5c\x9e\x94\x0f\xea\x2f\x58", 15, "\xc9\xff\x54\x5e\x07\xb8\x8a\x01\x5f\x05\xb2\x74\x54\x0a\xa1", "\x83\xb3\x44\x9b\x9f\x39\x55\x2d\xe9\x9d\xc2\x14\xa1\x19\x0b\x0b", }, { GCRY_CIPHER_AES128, "\xbd\xe3\xb2\xf2\x04\xd1\xe9\xf8\xb0\x6b\xc4\x7f\x97\x45\xb3\xd1", "\xae\x06\x55\x6f\xb6\xaa\x78\x90\xbe\xbc\x18\xfe", "\x18\x60\xf7\x62\xeb\xfb\xd0\x82\x84\xe4\x21\x70\x2d\xe0\xde\x18" "\xba\xa9\xc9\x59\x62\x91\xb0\x84\x66\xf3\x7d\xe2\x1c\x7f", 30, "\x6b\x3d\xb4\xda\x3d\x57\xaa\x94\x84\x2b\x98\x03\xa9\x6e\x07\xfb" "\x6d\xe7", 18, "\x62\x98\xb2\x96\xe2\x4e\x8c\xc3\x5d\xce\x0b\xed\x48\x4b\x7f\x30" "\xd5\x80", "\x3e\x37\x70\x94\xf0\x47\x09\xf6\x4d\x7b\x98\x53\x10\xa4\xdb\x84", }, { GCRY_CIPHER_AES128, "\xf9\x01\xcf\xe8\xa6\x96\x15\xa9\x3f\xdf\x7a\x98\xca\xd4\x81\x79", "\x62\x45\x70\x9f\xb1\x88\x53\xf6\x8d\x83\x36\x40", "\x75\x76\xf7\x02\x8e\xc6\xeb\x5e\xa7\xe2\x98\x34\x2a\x94\xd4\xb2" "\x02\xb3\x70\xef\x97\x68\xec\x65\x61\xc4\xfe\x6b\x7e\x72\x96\xfa" "\x85\x9c\x21", 35, "\xe4\x2a\x3c\x02\xc2\x5b\x64\x86\x9e\x14\x6d\x7b\x23\x39\x87\xbd" "\xdf\xc2\x40\x87\x1d", 21, "\x39\x1c\xc3\x28\xd4\x84\xa4\xf4\x64\x06\x18\x1b\xcd\x62\xef\xd9" "\xb3\xee\x19\x7d\x05", "\x2d\x15\x50\x6c\x84\xa9\xed\xd6\x5e\x13\xe9\xd2\x4a\x2a\x6e\x70", }, { GCRY_CIPHER_AES256, "\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", "\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", "", 0, "", 0, "", "\x07\xf5\xf4\x16\x9b\xbf\x55\xa8\x40\x0c\xd4\x7e\xa6\xfd\x40\x0f", }, { GCRY_CIPHER_AES256, "\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", "\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", "", 0, "\x01\x00\x00\x00\x00\x00\x00\x00", 8, "\xc2\xef\x32\x8e\x5c\x71\xc8\x3b", "\x84\x31\x22\x13\x0f\x73\x64\xb7\x61\xe0\xb9\x74\x27\xe3\xdf\x28", }, { GCRY_CIPHER_AES256, "\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", "\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", "", 0, "\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 12, "\x9a\xab\x2a\xeb\x3f\xaa\x0a\x34\xae\xa8\xe2\xb1", "\x8c\xa5\x0d\xa9\xae\x65\x59\xe4\x8f\xd1\x0f\x6e\x5c\x9c\xa1\x7e", }, { GCRY_CIPHER_AES256, "\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", "\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", "", 0, "\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 16, "\x85\xa0\x1b\x63\x02\x5b\xa1\x9b\x7f\xd3\xdd\xfc\x03\x3b\x3e\x76", "\xc9\xea\xc6\xfa\x70\x09\x42\x70\x2e\x90\x86\x23\x83\xc6\xc3\x66", }, { GCRY_CIPHER_AES256, "\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", "\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", "", 0, "\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 32, "\x4a\x6a\x9d\xb4\xc8\xc6\x54\x92\x01\xb9\xed\xb5\x30\x06\xcb\xa8" "\x21\xec\x9c\xf8\x50\x94\x8a\x7c\x86\xc6\x8a\xc7\x53\x9d\x02\x7f", "\xe8\x19\xe6\x3a\xbc\xd0\x20\xb0\x06\xa9\x76\x39\x76\x32\xeb\x5d", }, { GCRY_CIPHER_AES256, "\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", "\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", "", 0, "\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 48, "\xc0\x0d\x12\x18\x93\xa9\xfa\x60\x3f\x48\xcc\xc1\xca\x3c\x57\xce" "\x74\x99\x24\x5e\xa0\x04\x6d\xb1\x6c\x53\xc7\xc6\x6f\xe7\x17\xe3" "\x9c\xf6\xc7\x48\x83\x7b\x61\xf6\xee\x3a\xdc\xee\x17\x53\x4e\xd5", "\x79\x0b\xc9\x68\x80\xa9\x9b\xa8\x04\xbd\x12\xc0\xe6\xa2\x2c\xc4", }, { GCRY_CIPHER_AES256, "\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", "\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", "", 0, "\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 64, "\xc2\xd5\x16\x0a\x1f\x86\x83\x83\x49\x10\xac\xda\xfc\x41\xfb\xb1" "\x63\x2d\x4a\x35\x3e\x8b\x90\x5e\xc9\xa5\x49\x9a\xc3\x4f\x96\xc7" "\xe1\x04\x9e\xb0\x80\x88\x38\x91\xa4\xdb\x8c\xaa\xa1\xf9\x9d\xd0" "\x04\xd8\x04\x87\x54\x07\x35\x23\x4e\x37\x44\x51\x2c\x6f\x90\xce", "\x11\x28\x64\xc2\x69\xfc\x0d\x9d\x88\xc6\x1f\xa4\x7e\x39\xaa\x08", }, { GCRY_CIPHER_AES256, "\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", "\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", "\x01", 1, "\x02\x00\x00\x00\x00\x00\x00\x00", 8, "\x1d\xe2\x29\x67\x23\x7a\x81\x32", "\x91\x21\x3f\x26\x7e\x3b\x45\x2f\x02\xd0\x1a\xe3\x3e\x4e\xc8\x54", }, { GCRY_CIPHER_AES256, "\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", "\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", "\x01", 1, "\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 12, "\x16\x3d\x6f\x9c\xc1\xb3\x46\xcd\x45\x3a\x2e\x4c", "\xc1\xa4\xa1\x9a\xe8\x00\x94\x1c\xcd\xc5\x7c\xc8\x41\x3c\x27\x7f", }, { GCRY_CIPHER_AES256, "\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", "\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", "\x01", 1, "\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 16, "\xc9\x15\x45\x82\x3c\xc2\x4f\x17\xdb\xb0\xe9\xe8\x07\xd5\xec\x17", "\xb2\x92\xd2\x8f\xf6\x11\x89\xe8\xe4\x9f\x38\x75\xef\x91\xaf\xf7", }, { GCRY_CIPHER_AES256, "\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", "\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", "\x01", 1, "\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 32, "\x07\xda\xd3\x64\xbf\xc2\xb9\xda\x89\x11\x6d\x7b\xef\x6d\xaa\xaf" "\x6f\x25\x55\x10\xaa\x65\x4f\x92\x0a\xc8\x1b\x94\xe8\xba\xd3\x65", "\xae\xa1\xba\xd1\x27\x02\xe1\x96\x56\x04\x37\x4a\xab\x96\xdb\xbc", }, { GCRY_CIPHER_AES256, "\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", "\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", "\x01", 1, "\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 48, "\xc6\x7a\x1f\x0f\x56\x7a\x51\x98\xaa\x1f\xcc\x8e\x3f\x21\x31\x43" "\x36\xf7\xf5\x1c\xa8\xb1\xaf\x61\xfe\xac\x35\xa8\x64\x16\xfa\x47" "\xfb\xca\x3b\x5f\x74\x9c\xdf\x56\x45\x27\xf2\x31\x4f\x42\xfe\x25", "\x03\x33\x27\x42\xb2\x28\xc6\x47\x17\x36\x16\xcf\xd4\x4c\x54\xeb", }, { GCRY_CIPHER_AES256, "\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", "\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", "\x01", 1, "\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 64, "\x67\xfd\x45\xe1\x26\xbf\xb9\xa7\x99\x30\xc4\x3a\xad\x2d\x36\x96" "\x7d\x3f\x0e\x4d\x21\x7c\x1e\x55\x1f\x59\x72\x78\x70\xbe\xef\xc9" "\x8c\xb9\x33\xa8\xfc\xe9\xde\x88\x7b\x1e\x40\x79\x99\x88\xdb\x1f" "\xc3\xf9\x18\x80\xed\x40\x5b\x2d\xd2\x98\x31\x88\x58\x46\x7c\x89", "\x5b\xde\x02\x85\x03\x7c\x5d\xe8\x1e\x5b\x57\x0a\x04\x9b\x62\xa0", }, { GCRY_CIPHER_AES256, "\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", "\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", "\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 12, "\x02\x00\x00\x00", 4, "\x22\xb3\xf4\xcd", "\x18\x35\xe5\x17\x74\x1d\xfd\xdc\xcf\xa0\x7f\xa4\x66\x1b\x74\xcf", }, { GCRY_CIPHER_AES256, "\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", "\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", "\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x02\x00", 18, "\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x04\x00\x00\x00", 20, "\x43\xdd\x01\x63\xcd\xb4\x8f\x9f\xe3\x21\x2b\xf6\x1b\x20\x19\x76" "\x06\x7f\x34\x2b", "\xb8\x79\xad\x97\x6d\x82\x42\xac\xc1\x88\xab\x59\xca\xbf\xe3\x07", }, { GCRY_CIPHER_AES256, "\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", "\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", "\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x02\x00\x00\x00", 20, "\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x04\x00", 18, "\x46\x24\x01\x72\x4b\x5c\xe6\x58\x8d\x5a\x54\xaa\xe5\x37\x55\x13" "\xa0\x75", "\xcf\xcd\xf5\x04\x21\x12\xaa\x29\x68\x5c\x91\x2f\xc2\x05\x65\x43", }, { GCRY_CIPHER_AES256, "\xe6\x60\x21\xd5\xeb\x8e\x4f\x40\x66\xd4\xad\xb9\xc3\x35\x60\xe4" "\xf4\x6e\x44\xbb\x3d\xa0\x01\x5c\x94\xf7\x08\x87\x36\x86\x42\x00", "\xe0\xea\xf5\x28\x4d\x88\x4a\x0e\x77\xd3\x16\x46", "", 0, "", 0, "", "\x16\x9f\xbb\x2f\xbf\x38\x9a\x99\x5f\x63\x90\xaf\x22\x22\x8a\x62", }, { GCRY_CIPHER_AES256, "\xba\xe8\xe3\x7f\xc8\x34\x41\xb1\x60\x34\x56\x6b\x7a\x80\x6c\x46" "\xbb\x91\xc3\xc5\xae\xdb\x64\xa6\xc5\x90\xbc\x84\xd1\xa5\xe2\x69", "\xe4\xb4\x78\x01\xaf\xc0\x57\x7e\x34\x69\x9b\x9e", "\x4f\xbd\xc6\x6f\x14", 5, "\x67\x1f\xdd", 3, "\x0e\xac\xcb", "\x93\xda\x9b\xb8\x13\x33\xae\xe0\xc7\x85\xb2\x40\xd3\x19\x71\x9d", }, { GCRY_CIPHER_AES256, "\x65\x45\xfc\x88\x0c\x94\xa9\x51\x98\x87\x42\x96\xd5\xcc\x1f\xd1" "\x61\x32\x0b\x69\x20\xce\x07\x78\x7f\x86\x74\x3b\x27\x5d\x1a\xb3", "\x2f\x6d\x1f\x04\x34\xd8\x84\x8c\x11\x77\x44\x1f", "\x67\x87\xf3\xea\x22\xc1\x27\xaa\xf1\x95", 10, "\x19\x54\x95\x86\x0f\x04", 6, "\xa2\x54\xda\xd4\xf3\xf9", "\x6b\x62\xb8\x4d\xc4\x0c\x84\x63\x6a\x5e\xc1\x20\x20\xec\x8c\x2c", }, { GCRY_CIPHER_AES256, "\xd1\x89\x47\x28\xb3\xfe\xd1\x47\x3c\x52\x8b\x84\x26\xa5\x82\x99" "\x59\x29\xa1\x49\x9e\x9a\xd8\x78\x0c\x8d\x63\xd0\xab\x41\x49\xc0", "\x9f\x57\x2c\x61\x4b\x47\x45\x91\x44\x74\xe7\xc7", "\x48\x9c\x8f\xde\x2b\xe2\xcf\x97\xe7\x4e\x93\x2d\x4e\xd8\x7d", 15, "\xc9\x88\x2e\x53\x86\xfd\x9f\x92\xec", 9, "\x0d\xf9\xe3\x08\x67\x82\x44\xc4\x4b", "\xc0\xfd\x3d\xc6\x62\x8d\xfe\x55\xeb\xb0\xb9\xfb\x22\x95\xc8\xc2", }, { GCRY_CIPHER_AES256, "\xa4\x41\x02\x95\x2e\xf9\x4b\x02\xb8\x05\x24\x9b\xac\x80\xe6\xf6" "\x14\x55\xbf\xac\x83\x08\xa2\xd4\x0d\x8c\x84\x51\x17\x80\x82\x35", "\x5c\x9e\x94\x0f\xea\x2f\x58\x29\x50\xa7\x0d\x5a", "\x0d\xa5\x52\x10\xcc\x1c\x1b\x0a\xbd\xe3\xb2\xf2\x04\xd1\xe9\xf8" "\xb0\x6b\xc4\x7f", 20, "\x1d\xb2\x31\x6f\xd5\x68\x37\x8d\xa1\x07\xb5\x2b", 12, "\x8d\xbe\xb9\xf7\x25\x5b\xf5\x76\x9d\xd5\x66\x92", "\x40\x40\x99\xc2\x58\x7f\x64\x97\x9f\x21\x82\x67\x06\xd4\x97\xd5", }, { GCRY_CIPHER_AES256, "\x97\x45\xb3\xd1\xae\x06\x55\x6f\xb6\xaa\x78\x90\xbe\xbc\x18\xfe" "\x6b\x3d\xb4\xda\x3d\x57\xaa\x94\x84\x2b\x98\x03\xa9\x6e\x07\xfb", "\x6d\xe7\x18\x60\xf7\x62\xeb\xfb\xd0\x82\x84\xe4", "\xf3\x7d\xe2\x1c\x7f\xf9\x01\xcf\xe8\xa6\x96\x15\xa9\x3f\xdf\x7a" "\x98\xca\xd4\x81\x79\x62\x45\x70\x9f", 25, "\x21\x70\x2d\xe0\xde\x18\xba\xa9\xc9\x59\x62\x91\xb0\x84\x66", 15, "\x79\x35\x76\xdf\xa5\xc0\xf8\x87\x29\xa7\xed\x3c\x2f\x1b\xff", "\xb3\x08\x0d\x28\xf6\xeb\xb5\xd3\x64\x8c\xe9\x7b\xd5\xba\x67\xfd", }, { GCRY_CIPHER_AES256, "\xb1\x88\x53\xf6\x8d\x83\x36\x40\xe4\x2a\x3c\x02\xc2\x5b\x64\x86" "\x9e\x14\x6d\x7b\x23\x39\x87\xbd\xdf\xc2\x40\x87\x1d\x75\x76\xf7", "\x02\x8e\xc6\xeb\x5e\xa7\xe2\x98\x34\x2a\x94\xd4", "\x9c\x21\x59\x05\x8b\x1f\x0f\xe9\x14\x33\xa5\xbd\xc2\x0e\x21\x4e" "\xab\x7f\xec\xef\x44\x54\xa1\x0e\xf0\x65\x7d\xf2\x1a\xc7", 30, "\xb2\x02\xb3\x70\xef\x97\x68\xec\x65\x61\xc4\xfe\x6b\x7e\x72\x96" "\xfa\x85", 18, "\x85\x7e\x16\xa6\x49\x15\xa7\x87\x63\x76\x87\xdb\x4a\x95\x19\x63" "\x5c\xdd", "\x45\x4f\xc2\xa1\x54\xfe\xa9\x1f\x83\x63\xa3\x9f\xec\x7d\x0a\x49", }, { GCRY_CIPHER_AES256, "\x3c\x53\x5d\xe1\x92\xea\xed\x38\x22\xa2\xfb\xbe\x2c\xa9\xdf\xc8" "\x82\x55\xe1\x4a\x66\x1b\x8a\xa8\x2c\xc5\x42\x36\x09\x3b\xbc\x23", "\x68\x80\x89\xe5\x55\x40\xdb\x18\x72\x50\x4e\x1c", "\x73\x43\x20\xcc\xc9\xd9\xbb\xbb\x19\xcb\x81\xb2\xaf\x4e\xcb\xc3" "\xe7\x28\x34\x32\x1f\x7a\xa0\xf7\x0b\x72\x82\xb4\xf3\x3d\xf2\x3f" "\x16\x75\x41", 35, "\xce\xd5\x32\xce\x41\x59\xb0\x35\x27\x7d\x4d\xfb\xb7\xdb\x62\x96" "\x8b\x13\xcd\x4e\xec", 21, "\x62\x66\x60\xc2\x6e\xa6\x61\x2f\xb1\x7a\xd9\x1e\x8e\x76\x76\x39" "\xed\xd6\xc9\xfa\xee", "\x9d\x6c\x70\x29\x67\x5b\x89\xea\xf4\xba\x1d\xed\x1a\x28\x65\x94", }, { GCRY_CIPHER_AES256, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", "", 0, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x4d\xb9\x23\xdc\x79\x3e\xe6\x49\x7c\x76\xdc\xc0\x3a\x98\xe1\x08", 32, "\xf3\xf8\x0f\x2c\xf0\xcb\x2d\xd9\xc5\x98\x4f\xcd\xa9\x08\x45\x6c" "\xc5\x37\x70\x3b\x5b\xa7\x03\x24\xa6\x79\x3a\x7b\xf2\x18\xd3\xea", "\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", }, { GCRY_CIPHER_AES256, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", "", 0, "\xeb\x36\x40\x27\x7c\x7f\xfd\x13\x03\xc7\xa5\x42\xd0\x2d\x3e\x4c" "\x00\x00\x00\x00\x00\x00\x00\x00", 24, "\x18\xce\x4f\x0b\x8c\xb4\xd0\xca\xc6\x5f\xea\x8f\x79\x25\x7b\x20" "\x88\x8e\x53\xe7\x22\x99\xe5\x6d", "\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", + }, + /* Large block testing */ + { + GCRY_CIPHER_AES128, + "\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", + "\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", + "", + 0, + "\x72\x94\x7b\x5d\x3c\x14\xc0\xa6\x27\x8d\x8d\xee\xbd\xe8\x8c\x6a" + "\x21\x34\xce\x64\x8f\x01\x01\xc6\xe4\x5d\xed\x2e\xb9\xec\xac\x53" + "\xf2\x07\xed\x60\xc8\xa2\x2f\x2e\x83\x0e\xf2\xbc\x42\x51\x24\x3b" + "\x41\x4f\x26\x84\xf0\x25\x69\x3f\x38\x29\xfb\xe9\xbb\x1a\x94\xd1" + "\x94\x0c\xce\xad\x8e\x66\xeb\xda\xc9\x1c\x72\x5a\x7f\x95\x4f\x9c" + "\x02\x27\x79\x8f\xe7\x51\x51\x3d\x1e\x2c\x4e\xcd\x07\xe5\xd1\xf0" + "\x6c\x95\x82\x37\x00\x50\x5e\xff\x82\xfb\x69\x0b\x4e\x7f\x10\x12" + "\x7d\x18\x7f\xa8\x88\x59\xfb\x55\x9b\x70\x36\xfc\xde\x75\xed\x77" + "\xf9\x09\x87\x29\x30\x7c\x81\x41\x12\xc2\xbd\xcd\x9f\x86\x98\x38" + "\x96\x44\x4c\xda\x2e\xbe\x7a\xfb\xdd\x4a\x4e\xa0\x84\x94\xd5\x76" + "\xa6\xae\x02\xcb\x1b\xd4\xd8\xcb\xa5\x24\x28\xe1\x3c\x1e\xdc\x3d" + "\x25\x50\xe7\xfb\x92\xad\xd9\x80\x33\xe0\xb2\x50\x07\xd4\x43\x40" + "\x41\x63\x98\x63\xa6\x1a\xfc\x56\x84\x3f\xf7\x4f\x31\xe7\xfe\xc5" + "\x73\x52\xfd\x6d\x9b\xbb\x9b\xf8\x19\xf8\xdc\x9f\x3a\x88\xa6\x7c" + "\xf3\x6b\xbe\xde\xda\x05\x2e\x79\x54\xb9\x3e\x59\x43\x0a\x1b\x16" + "\xcf\x94\x97\x71\x03\x74\x12\x37\xaf\xd4\x0a\x4b\x30\x16\x9b\x8b" + "\x9f\xae\x78\x46\x83\xde\x34\xc5\x31\x71\x67\x5e\xdb\x8d\x93\x71" + "\x90\x03\x72\x00\x9f\x4e\x1e\x7d\xf3\x3f\xf8\x31\xe7\xf6\xb4\x6d" + "\x8d\xdc\xa0\x85\x32\x7b\x32\x40\x8c\xa9\x90\x69\xac\x03\xdb\xd4" + "\xa5\x62\x9c\xfd\x78\xde\xc8\x4a\x18\x67\xa0\xee\x5e\x1e\xad\x1a" + "\x1c\xee\x78\xbd\xea\xdc\xc8\x34\xd1\x92\x20\xa7\x0d\x12\x90\x88" + "\x91\xe4\x6c\x3c\x06\x78\x13\x00\xdc\xc7\x3e\xd7\x91\xf7\xc1\xd6" + "\x5a\x99\x95\x23\xb5\xd8\x3d\x0f\x12\xaf\x25\xd8\xcf\xe8\x27\x7f" + "\xbc\x7c\xe2\xad\x34\x66\x7f\xfb\xf5\xa8\x11\xc1\xe6\x04\x37\x41" + "\xaf\x96\xb3\xb7\xee\x05\xf5\xd7\x7c\xc6\xfe\x2e\xa9\x07\x47\x08" + "\xa4\x50\x65\xc0\x2e\xd7\x27\xd8\x70\x8c\xf1\x12\x30\x4a\x82\xf6" + "\xb7\x68\xdb\x9d\x73\xc2\x82\x3d\x44\xda\xfb\xdd\x03\xc1\xdc\xfc" + "\x3f\x7f\x2e\xe2\xd3\x73\x24\xaf\xd1\x35\xa9\x4f\x3a\xad\x9d\x5c" + "\xd7\xc6\xa3\xb1\x11\xf1\xbb\xa0\x23\xe1\x22\x88\x5b\x10\xb3\xd6" + "\x01\x78\x5f\x9e\x4d\x96\x7b\xeb\x81\x6b\xce\x2d\xf5\x6a\xd1\xa8" + "\xb7\x56\xdd\xd0\x4b\xb0\xc9\x64\x7a\x2f\x63\xcb\xd6\x61\x84\x4b" + "\x9e\x4d\x0b\x2c\x99\xbc\xa2\x94\xf5\x07\x20\xe6\xe9\xc2\xd2\xa6" + "\x1c\x37\xd5\x88\x01\x71\xe2\x16\xcd\x10\x7a\x07\x8b\xf3\xb5\x49" + "\x75\xbe\x0b\xe1\xb2\x28\x15\x88\x2b\xb4\xee\x34\xfd\x67\x30\xd8" + "\xdc\x38\x90\x66\xb6\x51\x90\xb3\xdb\xee\x4e\x66\xc3\x05\xdf\xee" + "\x32\xac\x8b\xa2\x00\xcc\xff\xa2\x52\x19\x79\x7e\x6c\xc9\x68\xb2" + "\xab\xe4\x69\x11\xea\x00\xc9\x2b\x58\x77\x8b\x6c\x28\x0e\x40\x42" + "\xcc\xa7\xb2\x58\xed\x5e\x0b\x19\x49\xe5\x5e\xb1\xb5\x24\x61\x63" + "\x7d\x5b\x6a\x7d\x3d\xc1\x6e\x09\x64\x43\x66\x31\x3c\xb0\x26\x2e" + "\xc8\x27\xf6\x5a\x5f\x22\x94\x42\x62\x2a\xf6\x5a\x7d\xc2\x4a\x0d" + "\xd2\xad\xaa\x0e\xb2\xa4\x29\x1c\xb8\x3b\xaa\xc9\x1d\x1a\x30\xf8" + "\x0b\x35\xb2\x84\x75\xc3\x08\x0c\xe5\x36\xa9\xff\xfe\xb9\xc2\xb7" + "\x51\xab\x2d\x9d\x3e\x1c\x08\x8c\x6c\x64\xe1\xd9\x97\xf4\xfc\x4d" + "\x77\x6d\x0e\xce\x73\x0b\x7f\x57\x41\xed\xdf\x96\x11\xb3\xcc\x61" + "\xe8\x12\x31\x16\x72\x4c\x10\xd4\x52\x14\x4c\x83\xaa\x3c\x29\x6c" + "\x51\x40\x9a\x4d\x9b\xd0\xe6\x7f\xad\x31\x54\x88\x90\xe1\xa8\x0e" + "\xd8\xf4\x84\x11\xdb\x02\x41\xff\xb0\x8a\x92\x95\x97\xd6\x98\x8a" + "\xa0\x43\xda\x70\xbb\x17\xd0\x5a\x81\x3e\xf7\xcf\xc9\x33\xd9\x76" + "\x2f\x53\xa2\xac\xa0\x8a\x73\xe4\x0c\x81\xbe\x26\x01\x3f\x6d\x79" + "\x8a\x37\x59\x5b\x0a\x9a\x10\x6b\x04\x30\xed\xda\x11\x73\x73\xd9" + "\xa2\x9a\xf8\x8e\x67\x82\x5a\x8d\xc0\x52\xe8\x42\x89\xcd\x9c\xb1" + "\x5c\x3d\xd4\x75\x03\x71\x03\x3f\xdc\x6b\x79\xb4\x02\xb6\xac\xc4" + "\x11\x0f\x61\xc8\xf7\x5d\xc6\xbf\x48\x02\xa3\xdc\xa8\x37\x10\x85" + "\xb2\x8d\xbd\xb0\x79\x09\xb0\x5f\x30\x6c\x40\xba\x03\xbb\x22\xcc" + "\x80\xa1\xc3\x91\x88\x25\x92\xbe\xa6\xfa\x14\x77\x56\xb3\xc0\xb5" + "\x69\x8c\x6f\xed\x21\xaf\x0c\x79\x07\x64\xa2\xea\xeb\x47\x2c\x1e" + "\x7d\x6c\x12\xae\x75\xc4\xee\x12\x46\x72\x87\x65\x73\x51\xee\xf8" + "\x08\x63\x20\xa1\x61\xca\x73\x8f\xdf\xcb\x97\xf8\xfc\xb0\x56\xea" + "\x34\x9d\xce\xb8\x91\xb8\xfc\xec\x76\xd0\x71\xb7\x92\xc9\xb2\x28" + "\xee\x0b\x5d\x7c\x4a\xf6\x73\x4d\xc2\x5b\x5b\xae\x7b\xa6\x9c\xba" + "\x29\x7d\x7d\x3c\x29\x01\x04\x2d\xd1\x6c\x8d\x8d\xe5\xb4\x6b\xf9" + "\x2a\x83\xb8\x14\x00\x1c\x91\x72\x5e\x8f\x13\x56\x6d\x9b\x6d\x27" + "\xe8\x22\x55\x4b\x2f\x8a\x31\x16\x98\x03\x51\x73\xa7\x2e\x18\x81" + "\x51\x0a\x8f\x6d\x17\xd0\xea\x04\x1c\x11\xb9\x6b\x8e\xaa\x76", + 1023, + "\x24\x28\x57\xa0\x3c\x12\xe2\x6a\x65\x97\x96\x75\xb3\x75\x67\x4c" + "\xd0\xc8\xa7\x07\x7d\x55\x10\xbc\x11\xfe\x45\xbe\x74\x27\x74\xa3" + "\x8b\xb8\x51\x0d\x2e\xf0\x0c\x83\xed\xe4\x8b\x15\xf2\xae\xd8\xd5" + "\xed\xd8\x76\x0d\x0b\x5b\x7b\x5a\x17\x83\xf3\x37\xe5\x81\x90\xe8" + "\x15\xb4\xec\xf8\x5a\x00\x72\xf2\xbb\x68\x0a\xc9\x6c\x4a\x80\x45" + "\x04\xa5\x7e\xfa\xf3\x45\x08\x65\xd0\xd6\xcd\x08\xd1\x1f\x45\x6b" + "\x23\xa9\x0f\xe1\x10\x90\x26\x48\x23\x23\xd2\x60\xc4\x16\x31\x03" + "\x30\xbe\xf0\xd0\xa0\xa7\xcf\xaa\xe6\x27\x0e\xd6\x7b\x79\xf1\x2b" + "\x29\x27\x57\x5a\xb7\xf5\xf8\xb4\x35\x3c\xb5\x10\xb8\xbf\xbe\xad" + "\xdb\x9b\x3d\x35\x63\xac\x9b\xfe\x86\x69\x2c\x54\xf5\x7c\x7f\xd6" + "\xcd\x33\x9f\x57\x7f\xce\x72\x18\x60\x2e\x20\x33\xc9\x13\x9f\x60" + "\x5f\x67\x24\xc2\xbb\x9e\x63\x80\xcf\x96\xb9\xf0\xf1\x9e\xcc\x5a" + "\x61\x02\x6d\xab\x4c\xf7\x13\xe4\x48\x0f\x9f\xc9\x24\x8e\x40\x06" + "\x53\x30\xac\xd9\xe8\xf5\xcd\xd4\xcf\x99\x1f\x3c\x08\x74\x38\x7e" + "\x0b\x76\x0d\xc3\xbd\x2a\x75\x3a\x55\x0c\xc6\xd3\x50\x59\x53\xf2" + "\x14\x1d\x09\xb0\xfa\x8d\xc2\x5e\x6b\x79\xed\x5e\x10\xcc\x1c\xbe" + "\x03\x75\x6d\x23\x44\xe8\xd6\x4d\x8f\xe4\xd6\x1a\x16\x83\x79\x72" + "\xdc\x51\x25\x61\x75\xe7\x00\x09\xdf\xfe\x0c\x6c\x99\xa8\xb0\xfc" + "\xbf\xb6\x7f\xae\x0a\x75\x2e\xd4\x69\xfe\xf1\xb7\x68\xbe\x07\xf0" + "\x9c\xa3\x82\x1f\x4d\x06\xa7\x73\x53\xbd\x98\x99\x93\x1b\xc9\xb6" + "\x04\x5e\xc0\xc1\xd8\x53\x7e\x6f\xd9\x4e\xa0\x37\xab\x71\x92\xc7" + "\x97\x4b\x80\x40\x14\xd0\xd0\xee\x93\xfb\xd5\x76\xce\xd7\x9e\x74" + "\xee\x5d\xe6\x79\xb2\x92\xbb\xff\x63\x19\x61\x64\xcc\x60\x80\x8b" + "\x9c\x1f\x38\x01\x43\xf7\xa6\xcd\x20\x5d\x1d\x2a\x2a\x25\xf4\xd5" + "\x17\x3d\x9c\xd2\x56\x8c\x76\x4e\xa0\xba\x24\x55\x55\xd4\x87\x78" + "\xde\x30\xe8\x6f\x39\xa5\x22\x91\x2b\x7b\x20\x6f\xf6\x44\xff\xec" + "\x29\x4e\xc8\x30\xf7\x23\x18\xef\xb8\x33\xfb\x5f\xf2\xe2\xd8\xc1" + "\xe3\x0f\x24\x19\xff\x99\x7e\xa2\xdb\x78\xde\xc3\x92\x47\x9b\x32" + "\xd6\xfa\xb7\x34\x14\xa4\xde\xd0\xa4\x6f\x7b\x03\x90\x80\x7a\x1e" + "\xb7\xc7\xc3\x75\x98\xa6\x76\xfc\xa6\x38\xa3\xf6\x17\xe8\x90\x25" + "\x28\x66\x41\x78\xe9\x70\x44\xbc\x62\x64\xf5\xaa\xd8\x62\x09\xf3" + "\xff\x05\xd5\x4e\xea\x8d\xf0\x0e\x4e\x3c\x37\xbe\x30\xe6\x69\x15" + "\xc5\x7b\xa6\x67\x1a\x74\xca\x4f\x0f\x5c\xf3\xac\x20\xaa\xc3\xad" + "\xf5\xb3\x58\x8e\x22\x53\x3d\xe8\x0a\x1b\x33\x88\xf1\x8d\x9c\xc8" + "\x5a\xb6\xd3\xde\x1a\x7a\x21\x12\x1e\x70\x0e\x52\x90\x24\xe0\x1c" + "\xaa\x04\x79\xbc\x58\x42\xcb\xe1\x42\x82\xbe\xeb\x17\xd6\xd9\x8c" + "\xc5\xe8\x77\xde\x77\xb5\x31\xf5\x7f\x09\x8b\x7d\x59\x6e\xbd\xe0" + "\x7b\x0f\xe6\x29\x37\x7b\x19\x90\x69\x33\x0a\xbe\x50\xa5\x11\xba" + "\xc5\x90\x78\x31\xfc\x1e\x6c\x8e\x50\x99\x2b\xd9\x50\x39\xaa\x80" + "\x19\x59\xae\x1e\x7a\x7d\xea\xbe\x92\x0e\xc1\xd4\x99\x71\x50\xb2" + "\x46\x0e\x39\x73\x45\x92\x8e\xd7\xb3\xcd\xf7\x37\x8e\x78\x2b\x2b" + "\xba\x33\xc1\x3e\xdd\xac\x9d\x09\xcd\xb0\x7e\x78\x05\x70\x44\x98" + "\x8d\xcd\xf3\xf4\x55\x07\x6a\x75\x66\x6a\xd2\xf2\x4a\x95\x6b\x07" + "\xfc\x8d\x6d\xe9\x40\xc5\x94\x19\xb5\x29\x5c\xaa\xb0\x7b\x2b\x8d" + "\x64\x41\xfd\x10\x58\xba\x6c\x1f\x7e\x88\x5f\x77\x8c\xe0\x3a\xda" + "\x7d\xed\xc4\xf1\x30\xce\x8d\x47\xd8\xe2\x8c\xca\xea\xf8\xb7\x73" + "\x9d\xb4\xfc\x06\x09\x17\x20\x00\x96\xe4\xd2\x07\x01\x10\x44\xef" + "\x7e\x18\x74\xac\xba\xe3\x26\x0d\x11\x27\xbf\xf3\xbb\x06\x1c\x49" + "\xd7\xae\x79\xe1\xaf\xd8\x66\x48\x03\xb6\x08\x66\x79\x11\xc5\x68" + "\x47\xbc\x4b\xfe\xc4\xa6\x7b\x3a\x66\xcd\x9f\x93\x70\xc2\x42\xd9" + "\xac\x54\x36\x73\x1b\x3a\x89\x1f\x13\xc7\x63\x9e\x43\xbf\xdd\xd7" + "\x54\xc7\xda\x6f\x74\x83\x81\x27\x19\xb3\xde\x1a\x14\xec\x0b\x96" + "\xee\x12\x02\xd1\x9f\x30\xe1\xef\xb8\xb4\xe9\xa4\x72\xc1\x48\xbc" + "\x23\x21\x64\x32\x0d\xac\x49\x6e\x53\x80\x37\x10\x2d\xcf\x6f\x11" + "\xf3\xd0\xf3\x02\xb6\x9d\x6e\x3c\x44\x39\x4d\xee\x8b\x8f\xea\xfa" + "\x20\xf4\x98\x67\x9c\xe3\x12\x82\xa8\xbe\x1c\x3a\x1c\x51\x81\x9d" + "\xc0\xfe\x46\x79\xd0\x19\x6b\xf1\x5d\xbb\x4d\xde\x42\xc9\x72\x93" + "\x62\x65\xb5\x88\xb1\x5f\x92\xfe\x56\x56\x58\xfb\x7a\x81\x7c\x02" + "\xb0\xc0\x53\x84\x6f\x13\x20\x53\xec\x49\x93\xae\x7e\x3c\x3f\xdf" + "\xe7\xba\xa0\x40\x24\x10\xd4\xe6\xf5\xed\x65\xd3\x21\x36\xb1\xe6" + "\x11\x0a\x47\xbc\xd3\x21\x33\x30\x03\x37\x8c\x45\xe5\xdd\xb0\xd5" + "\xcb\x80\x42\xdd\x84\xd6\x70\xf0\xbb\x5b\x44\xe0\x84\x8b\x83\x7c" + "\xcb\xec\x6a\x28\xa3\xf3\x4a\x6c\x0d\xb0\x79\x34\x13\x10\x64\xfc" + "\xee\x12\x55\x82\x25\x25\x30\xb9\xa6\xf8\x3c\x81\x36\xcd\xef", + "\xce\xc3\x13\x6c\x40\x2a\xcc\x51\xa1\xce\xb3\xed\xe8\xa6\x5b\x04", } }; gcry_cipher_hd_t hde, hdd; unsigned char out[MAX_DATA_LEN]; unsigned char tag[16]; int i, keylen; gcry_error_t err = 0; size_t taglen2; if (verbose) fprintf (stderr, " Starting GCM-SIV checks.\n"); for (i = 0; i < sizeof (tv) / sizeof (tv[0]); i++) { 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-SIV mode for %s [%i]\n", gcry_cipher_algo_name (tv[i].algo), tv[i].algo); err = gcry_cipher_open (&hde, tv[i].algo, GCRY_CIPHER_MODE_GCM_SIV, 0); if (!err) err = gcry_cipher_open (&hdd, tv[i].algo, GCRY_CIPHER_MODE_GCM_SIV, 0); if (err) { fail ("aes-gcm-siv, gcry_cipher_open failed: %s\n", gpg_strerror (err)); return; } keylen = gcry_cipher_get_algo_keylen (tv[i].algo); if (!keylen) { fail ("aes-gcm-siv, gcry_cipher_get_algo_keylen failed\n"); return; } err = gcry_cipher_setkey (hde, tv[i].key, keylen); if (!err) err = gcry_cipher_setkey (hdd, tv[i].key, keylen); if (err) { fail ("aes-gcm-siv, gcry_cipher_setkey failed: %s\n", gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } err = gcry_cipher_setiv (hde, tv[i].nonce, 12); if (!err) err = gcry_cipher_setiv (hdd, tv[i].nonce, 12); if (err) { fail ("aes-gcm-siv, gcry_cipher_setiv failed: %s\n", gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } if (tv[i].adlen >= 0) { err = gcry_cipher_authenticate (hde, tv[i].ad, tv[i].adlen); if (!err) err = gcry_cipher_authenticate (hdd, tv[i].ad, tv[i].adlen); if (err) { fail ("aes-gcm-siv, gcry_cipher_authenticate failed: %s\n", gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } } err = gcry_cipher_info (hde, GCRYCTL_GET_TAGLEN, NULL, &taglen2); if (err) { fail ("cipher-siv, gcryctl_get_taglen failed (tv %d): %s\n", i, gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } if (taglen2 != 16) { fail ("cipher-siv, gcryctl_get_taglen returned bad length" " (tv %d): got=%zu want=%d\n", i, taglen2, 16); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } if (tv[i].inlen) { err = gcry_cipher_encrypt (hde, out, tv[i].inlen, tv[i].plaintext, tv[i].inlen); if (err) { fail ("aes-gcm-siv, gcry_cipher_encrypt (%d) failed: %s\n", i, gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } if (memcmp (tv[i].out, out, tv[i].inlen)) { mismatch (tv[i].out, tv[i].inlen, out, tv[i].inlen); fail ("aes-gcm-siv, encrypt mismatch entry %d\n", i); } err = gcry_cipher_gettag (hde, tag, taglen2); if (err) { fail ("aes-gcm-siv, gcry_cipher_gettag(%d) failed: %s\n", i, gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } if (memcmp (tv[i].tag, tag, taglen2)) { mismatch (tv[i].tag, taglen2, tag, taglen2); fail ("aes-gcm-siv, tag mismatch entry %d\n", i); } err = gcry_cipher_set_decryption_tag (hdd, tag, taglen2); if (err) { fail ("aes-gcm-siv, gcry_cipher_set_decryption_tag (%d) failed: %s\n", i, gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } err = gcry_cipher_decrypt (hdd, out, tv[i].inlen, NULL, 0); if (err) { fail ("aes-gcm-siv, gcry_cipher_decrypt (%d) failed: %s\n", i, gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } if (memcmp (tv[i].plaintext, out, tv[i].inlen)) fail ("aes-gcm-siv, decrypt mismatch entry %d\n", i); err = gcry_cipher_checktag (hdd, tag, taglen2); if (err) { fail ("aes-gcm-siv, gcry_cipher_checktag (%d) failed: %s\n", i, gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } } else { err = gcry_cipher_gettag (hde, tag, taglen2); if (err) { fail ("aes-gcm-siv, gcry_cipher_gettag(%d) failed: %s\n", i, gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } if (memcmp (tv[i].tag, tag, taglen2)) { mismatch (tv[i].tag, taglen2, tag, taglen2); fail ("aes-gcm-siv, tag mismatch entry %d\n", i); } err = gcry_cipher_checktag (hdd, tv[i].tag, taglen2); if (err) { fail ("aes-gcm-siv, gcry_cipher_checktag (%d) failed: %s\n", i, gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } tag[13] ^= 0x4; err = gcry_cipher_checktag (hdd, tag, taglen2); if (gpg_err_code (err) != GPG_ERR_CHECKSUM) { fail ("aes-gcm-siv, gcry_cipher_checktag (%d) expected checksum fail: %s\n", i, gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } } gcry_cipher_close (hde); gcry_cipher_close (hdd); } if (verbose) fprintf (stderr, " Completed GCM-SIV checks.\n"); } static void _check_poly1305_cipher (unsigned int step) { static const struct tv { int algo; const char *key; const char *iv; int ivlen; const char *aad; int aadlen; const char *plaintext; int inlen; const char *out; const char *tag; } tv[] = { /* draft-irtf-cfrg-chacha20-poly1305-03 */ { GCRY_CIPHER_CHACHA20, "\x1c\x92\x40\xa5\xeb\x55\xd3\x8a\xf3\x33\x88\x86\x04\xf6\xb5\xf0" "\x47\x39\x17\xc1\x40\x2b\x80\x09\x9d\xca\x5c\xbc\x20\x70\x75\xc0", "\x00\x00\x00\x00\x01\x02\x03\x04\x05\x06\x07\x08", 12, "\xf3\x33\x88\x86\x00\x00\x00\x00\x00\x00\x4e\x91", 12, "\x49\x6e\x74\x65\x72\x6e\x65\x74\x2d\x44\x72\x61\x66\x74\x73\x20" "\x61\x72\x65\x20\x64\x72\x61\x66\x74\x20\x64\x6f\x63\x75\x6d\x65" "\x6e\x74\x73\x20\x76\x61\x6c\x69\x64\x20\x66\x6f\x72\x20\x61\x20" "\x6d\x61\x78\x69\x6d\x75\x6d\x20\x6f\x66\x20\x73\x69\x78\x20\x6d" "\x6f\x6e\x74\x68\x73\x20\x61\x6e\x64\x20\x6d\x61\x79\x20\x62\x65" "\x20\x75\x70\x64\x61\x74\x65\x64\x2c\x20\x72\x65\x70\x6c\x61\x63" "\x65\x64\x2c\x20\x6f\x72\x20\x6f\x62\x73\x6f\x6c\x65\x74\x65\x64" "\x20\x62\x79\x20\x6f\x74\x68\x65\x72\x20\x64\x6f\x63\x75\x6d\x65" "\x6e\x74\x73\x20\x61\x74\x20\x61\x6e\x79\x20\x74\x69\x6d\x65\x2e" "\x20\x49\x74\x20\x69\x73\x20\x69\x6e\x61\x70\x70\x72\x6f\x70\x72" "\x69\x61\x74\x65\x20\x74\x6f\x20\x75\x73\x65\x20\x49\x6e\x74\x65" "\x72\x6e\x65\x74\x2d\x44\x72\x61\x66\x74\x73\x20\x61\x73\x20\x72" "\x65\x66\x65\x72\x65\x6e\x63\x65\x20\x6d\x61\x74\x65\x72\x69\x61" "\x6c\x20\x6f\x72\x20\x74\x6f\x20\x63\x69\x74\x65\x20\x74\x68\x65" "\x6d\x20\x6f\x74\x68\x65\x72\x20\x74\x68\x61\x6e\x20\x61\x73\x20" "\x2f\xe2\x80\x9c\x77\x6f\x72\x6b\x20\x69\x6e\x20\x70\x72\x6f\x67" "\x72\x65\x73\x73\x2e\x2f\xe2\x80\x9d", 265, "\x64\xa0\x86\x15\x75\x86\x1a\xf4\x60\xf0\x62\xc7\x9b\xe6\x43\xbd" "\x5e\x80\x5c\xfd\x34\x5c\xf3\x89\xf1\x08\x67\x0a\xc7\x6c\x8c\xb2" "\x4c\x6c\xfc\x18\x75\x5d\x43\xee\xa0\x9e\xe9\x4e\x38\x2d\x26\xb0" "\xbd\xb7\xb7\x3c\x32\x1b\x01\x00\xd4\xf0\x3b\x7f\x35\x58\x94\xcf" "\x33\x2f\x83\x0e\x71\x0b\x97\xce\x98\xc8\xa8\x4a\xbd\x0b\x94\x81" "\x14\xad\x17\x6e\x00\x8d\x33\xbd\x60\xf9\x82\xb1\xff\x37\xc8\x55" "\x97\x97\xa0\x6e\xf4\xf0\xef\x61\xc1\x86\x32\x4e\x2b\x35\x06\x38" "\x36\x06\x90\x7b\x6a\x7c\x02\xb0\xf9\xf6\x15\x7b\x53\xc8\x67\xe4" "\xb9\x16\x6c\x76\x7b\x80\x4d\x46\xa5\x9b\x52\x16\xcd\xe7\xa4\xe9" "\x90\x40\xc5\xa4\x04\x33\x22\x5e\xe2\x82\xa1\xb0\xa0\x6c\x52\x3e" "\xaf\x45\x34\xd7\xf8\x3f\xa1\x15\x5b\x00\x47\x71\x8c\xbc\x54\x6a" "\x0d\x07\x2b\x04\xb3\x56\x4e\xea\x1b\x42\x22\x73\xf5\x48\x27\x1a" "\x0b\xb2\x31\x60\x53\xfa\x76\x99\x19\x55\xeb\xd6\x31\x59\x43\x4e" "\xce\xbb\x4e\x46\x6d\xae\x5a\x10\x73\xa6\x72\x76\x27\x09\x7a\x10" "\x49\xe6\x17\xd9\x1d\x36\x10\x94\xfa\x68\xf0\xff\x77\x98\x71\x30" "\x30\x5b\xea\xba\x2e\xda\x04\xdf\x99\x7b\x71\x4d\x6c\x6f\x2c\x29" "\xa6\xad\x5c\xb4\x02\x2b\x02\x70\x9b", "\xee\xad\x9d\x67\x89\x0c\xbb\x22\x39\x23\x36\xfe\xa1\x85\x1f\x38" }, /* draft-irtf-cfrg-chacha20-poly1305-03 */ { GCRY_CIPHER_CHACHA20, "\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f" "\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f", "\x07\x00\x00\x00\x40\x41\x42\x43\x44\x45\x46\x47", 12, "\x50\x51\x52\x53\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7", 12, "Ladies and Gentlemen of the class of '99: If I could offer you " "only one tip for the future, sunscreen would be it.", 114, "\xd3\x1a\x8d\x34\x64\x8e\x60\xdb\x7b\x86\xaf\xbc\x53\xef\x7e\xc2" "\xa4\xad\xed\x51\x29\x6e\x08\xfe\xa9\xe2\xb5\xa7\x36\xee\x62\xd6" "\x3d\xbe\xa4\x5e\x8c\xa9\x67\x12\x82\xfa\xfb\x69\xda\x92\x72\x8b" "\x1a\x71\xde\x0a\x9e\x06\x0b\x29\x05\xd6\xa5\xb6\x7e\xcd\x3b\x36" "\x92\xdd\xbd\x7f\x2d\x77\x8b\x8c\x98\x03\xae\xe3\x28\x09\x1b\x58" "\xfa\xb3\x24\xe4\xfa\xd6\x75\x94\x55\x85\x80\x8b\x48\x31\xd7\xbc" "\x3f\xf4\xde\xf0\x8e\x4b\x7a\x9d\xe5\x76\xd2\x65\x86\xce\xc6\x4b" "\x61\x16", "\x1a\xe1\x0b\x59\x4f\x09\xe2\x6a\x7e\x90\x2e\xcb\xd0\x60\x06\x91" }, /* generated with c implementation */ { GCRY_CIPHER_CHACHA20, "\x1c\x92\x40\xa5\xeb\x55\xd3\x8a\xf3\x33\x88\x86\x04\xf6\xb5\xf0" "\x47\x39\x17\xc1\x40\x2b\x80\x09\x9d\xca\x5c\xbc\x20\x70\x75\xc0", "\x00\x00\x00\x00\x01\x02\x03\x04\x05\x06\x07\x08", 12, "\xf3\x33\x88\x86\x00\x00\x00\x00\x00\x00\x4e\x91", 12, "\xb0\x58\x83\x17\x3a\x8e\x69\xf2\x18\x9d\x71\xe4\x8a\x0b\x7a\xcd" "\xe2\xd8\xb9\x8b\xdf\x99\xc2\x6d\x05\x4b\x44\x1e\x65\x5d\xda\xd5" "\x79\xf0\x19\xab\x94\x50\xd0\xc5\x54\xfe\x76\xc8\xd9\xf3\x39\x33" "\x9c\x0f\x27\x89\x85\x99\xe3\xed\x5c\x31\x04\xa6\x20\xab\xb3\x78" "\xac\x31\xba\x21\x8c\xac\x70\xd1\xe2\x92\xd6\x50\x58\x69\xab\xd4" "\x38\xdc\x9c\x71\x81\xf7\xf1\x68\x10\x50\x07\x09\x0e\x51\x49\xd2" "\x10\x9a\x2e\x78\xfb\xc7\xd3\xc2\x84\xda\xf2\x52\x17\x2c\xa6\xe8" "\x56\x60\x80\x46\xed\xfb\x9f\xab\xc2\x01\xf0\x06\x6b\x6e\xcc\xf6" "\x55\x3e\x81\xc7\x71\x9f\x10\xf0\x8e\x5a\x4b\xf6\xae\x90\x75\x03" "\x4f\xb3\xb4\xff\x66\xfa\xe3\xb6\x1c\xca\x0c\x75\x8a\x08\x3d\xce" "\x58\x69\x9d\xa9\x19\x29\xda\x2f\xa1\xb2\xae\xa7\x83\xd5\x92\xc2" "\x15\xdc\xef\x76\xd2\xd1\x9f\xb4\x7f\x3e\xb3\x7a\xa8\x3e\xba\xa3" "\x9e\x2e\x73\xe3\x4d\xdc\x50\xba\x5b\xb0\x8b\x1a\x87\x21\x03\x93" "\x74\x20\x01\xda\x38\x85\x1c\x3c\x57\x51\x09\x0e\xd8\xfc\x2b\xef" "\x38\x8e\x11\xa4\x9e\x11\xcc\xc5\x9f\x4c\xc2\x0d\x3e\x5f\x73\x40" "\x5a\xf4\x5b\x57\x84\x6e\xc7\xd0\x8e\xad\x1c\x1b\xae\x59\xba\xf5" "\x77\xed\x44\x08\x9c\x9b\xfd\x88\xd9\x27\xe8\x43\xe8\xdd\x86\xfd" "\x05\x3a\xc2\x11\x88\x98\x87\xcb\xa1\x72\xc2\x52\x5c\xd1\x1a\x40" "\x80\xe2\x1e\xe8\x9b\x4e\x63\x9b\xfb\x58\x11\x44\x36\x35\x83\x9b" "\x20\x9b\x4b\x58\xef\x1f\xfa\xe1\xb0\xe0\xb8\x60\x87\x0b\xdb\x83" "\x6f\xeb\xc0\x80\x63\xa8\xc4\x22\x0f\x1d\xec\x9b\x44\xfa\xd3\x13" "\x75\xb0\xfe\x74\x3c\xde\x9e\xb4\x91\x72\xc5\xf6\x36\x14\x18\x2d" "\x15\x2e\x6b\x34\xcf\xed\x86\x4f\x1b\x56\xcf\x09\x8f\x3d\xd1\x8d" "\x01\x7c\xba\x6a\xf4\x82\xdc\xf6\x9e\xc9\x79\xd4\x9e\x50\xc2\x9a" "\x4f\x90\x10\x44\xd5\xcf\x6b\x1d\xb3\xce\x7c\xeb\x3f\x8f\xbc\xe6" "\x76\xad\x78\x97\xee\xaf\x66\x73\xe4\x11\xb9\x6c\xf4\xc1\x1a\x76" "\xd6\x54\x4c\x6c\x44\x58\xec\xd9\x8f\xf9\xc6\x7f\x71\x95\x04\xfe" "\x6b\x42\xd6\x4f\xc6\xa8\xc1\xfa\x1e\x2c\xf2\x49\x6a\x5a\xe5\x28" "\x34\x30\x05\xc1\x21\x3a\x5f\xfd\xaf\x61\x1f\xa0\x91\xd4\x17\xcf" "\x65\x9d\xf5\xdb\x4b\xc2\x3d\x12\xed\xe1\x4e\xf1\x34\x50\x13\xa7" "\x3f\xe6\x26\xcb\xc9\xb3\x64\x69\xa9\x82\x21\xec\x64\xa9\x2e\x83" "\xa9\x9d\xa0\xbe\x20\xef\x5f\x71\x45\xe7\x9f\x75\xa3\x72\x16\xef" "\x1b\xf7\x9a\x15\xe2\x75\x92\x39\xbb\xb1\x4f\x34\xf4\x88\x0d\xcf" "\xbf\xd6\xfe\x5d\x61\x14\x45\x83\xf9\x6a\x3e\x81\x0f\x14\x78\xda" "\x94\xe2\xce\x7d\x1c\x15\xd7\xe0\x95\x1d\xd8\x96\xc2\x11\xb1\x55" "\xae\xc6\x95\x43\x38\x0a\x01\xc2\x30\xb8\x1b\x12\x39\x98\x58\x20" "\xbd\x65\x50\x1d\x17\x13\x02\xb9\xe4\x88\x39\x72\xc8\x58\xa0\xa8" "\x8f\xb9\xc2\x78\x82\x3a\x56\xe8\x0d\xf9\x1b\xbb\xfb\xf0\x5b\xc4" "\x9a\x2d\xf0\xd5\x57\x6f\xce\x4b\xb6\x3e\x1b\xbf\x54\xb4\x3e\x4e" "\x52\x5c\x2e\x6b\x5e\x01\xd1\xb3\xb5\x16\x67\xe4\x16\xad\x3c\x4d" "\x1c\xb2\xc0\x54\xcc\xf9\xba\x11\x85\xdf\x43\x1a\xfb\x55\x9b\x88" "\x27\x9e\x17\x29\x41\x7d\x2a\xb4\xf6\x61\x93\xa5\x1f\x5b\xb3\x06" "\xbe\x86\x40\x11\xc6\xfc\x36\x44\xdb\xbf\x4c\x6b\x21\x15\xa9\x10" "\x01\xdc\x53\x9c\x57\x27\xbe\x55\x19\x86\x17\x96\xfa\xdc\x4d\xf4" "\xd9\x79\xbe\x6c\x29\x1b\xed\xbd\x09\x72\xb4\xbf\x88\xc7\x52\x39" "\x5f\x62\x35\xad\x41\x87\xa6\xaa\x99\x20\xbc\x7d\x97\x67\x83\xa5" "\xc3\x43\xc6\x7f\x31\xb9\x0c\xe1\x82\xa5\x66\x9a\x58\xe3\xaf\x6b" "\x59\x09\x5b\xad\xed\xc2\x57\x66\x4e\x72\xb0\xaa\x0d\xeb\x9c\x48" "\x3f\x0b\xaf\xc6\x46\x06\x54\x3a\x2a\x19\xb3\x9d\xde\xd9\xa0\xcf" "\x71\x69\x33\xe8\x2c\xa8\x56\x8c\x0b\xae\x41\xc7\xb5\xfd\xca\xea" "\x0f\xd1\xd7\xe0\x3e\xf6\xf5\xd1\xb2\x57\x21\x00\x32\xca\x02\x4d" "\x18\xbe\x2c\x25\xe9\xbe\x0a\x34\x44\x92\xaa\x43\x09\xf7\xb4\x35" "\xac\x65\xc3\xc1\x4c\x66\x74\x91\x9f\xae\xe2\x27\x37\x8a\xfe\x13" "\x57\xf0\x39\x30\xf0\x06\xef\xa0\x5f\x90\xb7\xfa\xd9\x42\x3e\xcb" "\xdc\x9c\x44\x36\x13\x8e\x66\xbc\x85\xe8\xfa\x2c\x73\xa5\x87\xbd" "\x63\x98\x42\x56\x1a\xe9\xc4\x80\xa1\x0e\xd5\x9a\x27\xd2\x82\x20" "\x08\xe5\x98\x60\x00\x6d\xd9\x53\x9b\xae\x67\xfb\x03\xff\x82\xf1" "\xc6\x9b\x0b\xf1\x2c\x97\x89\x1c\x8e\x84\xd0\xb3\x2a\x44\xa3\xb2" "\x77\x1d\xf2\x2e\x6a\xf7\x05\x67\x32\x21\xca\x39\x2e\x7f\x1a\x69" "\x21\xdd\xaa\xfc\x19\xad\xc5\xf8\xfe\x6f\x17\x9e\x32\x64\xf8\xeb" "\x98\x8a\x5e\x2e\x89\xea\xfb\xed\xd7\x09\x1a\x7f\xa5\xf6\xe3\xd4" "\x33\x60\xbb\xc2\x2b\x1a\xd6\x4c\x03\xe1\xc3\xc6\x90\x0e\x7a\x89" "\xe8\x50\x4b\x47\xc2\x91\x5d\x2a\x49\xf5\xb0\x5f\x69\xbb\x88\x51" "\x0c\xa2\xc0\x88\x99\x91\xcd\x77\x11\x31\x3a\x8f\x99\x03\xd7\x5e", 1024, "\x9d\x96\x71\x67\x3d\x66\x16\x72\x55\x29\x61\x42\x77\x99\x4a\x50" "\xdd\x2a\x80\x56\x8f\xb7\x50\x82\x80\x63\x47\x7b\xc1\x44\x3b\x02" "\x5b\xe8\x96\x93\x97\x6c\xff\x42\x90\x40\xf9\xe9\x93\xfe\x7e\xa3" "\x4c\xd9\xe8\xdc\xda\xf7\x8f\xcd\xe7\xa7\x1f\xaa\x7c\x8b\x07\xda" "\xf0\x70\x4d\x47\x8e\x87\x86\x71\x1e\x7a\x13\x7b\x9c\x42\x5d\x30" "\x0c\x04\xfb\x7b\xe0\x0e\xa7\xb1\x5c\x89\xf7\xdd\x81\x0a\xe0\xe4" "\xe2\x69\xa2\x36\x60\x45\x1c\xcc\x27\x2f\xaf\x70\x59\x6d\xc5\xb4" "\x40\x04\x69\x1d\xe8\xf3\xf5\x7e\x49\xd7\x81\x12\x5b\xd3\xc6\x77" "\x82\x5c\x9e\x91\x6b\x6b\x7d\xd7\x45\xb8\x39\x94\x0a\x1a\xb4\xc4" "\xff\xba\x05\x7b\x0b\xba\xe1\x81\x90\x29\xdd\xb5\x58\x0b\x1f\x82" "\x9e\x4d\xdd\x1b\xc1\x62\x14\x1a\x8f\xc1\x8c\xf6\x46\x07\xb2\xcd" "\x6a\xb5\xa1\x06\x4c\xc3\xa3\x3f\x02\x08\xe2\x29\x3c\x05\xbd\xcb" "\xf0\xfa\x27\xf1\x7b\x48\x45\x46\x62\x88\x01\xb8\xd3\x0a\x29\xbc" "\xd6\xbb\x20\xee\x75\x5f\x29\x0c\x47\x9e\x0f\x1d\xdf\x81\x39\x9a" "\x1c\x48\x69\x09\xeb\x42\xae\x71\x11\x4c\x53\x9c\x69\xa6\x71\x50" "\x45\x4d\x31\x71\xdd\xdb\xb1\x64\x37\xbf\x03\x76\xb2\x44\xf9\xbb" "\xa3\x25\x6b\xcf\xb0\x9f\x1d\x78\xdf\x93\xde\x2d\x57\x23\x6f\xff" "\x02\xf8\xc6\xf5\x5f\x4b\xd5\x8a\x15\xc2\x5f\x9d\x47\x3b\x2f\x8f" "\x36\x93\x4a\x96\xae\x57\xaa\xd7\x6e\xea\x45\x94\xfb\xa2\xab\x56" "\xae\x7e\xb3\xc5\x87\xa5\xd4\x2d\xf0\x99\x1e\x0a\x05\xb8\x33\xe4" "\x89\x6c\x9e\x6d\x8c\xf1\xb4\xaa\x1f\xaa\xfb\x4b\x40\x90\xc0\x50" "\xf3\x7d\x2a\x67\x68\x25\x0a\x9a\x89\x1f\x90\xfd\xb0\x9d\x7d\xaf" "\x72\x22\xeb\x22\xb9\x63\x5f\x2c\x54\x49\xa3\x99\xc4\x74\xab\xc0" "\x2c\x85\x31\x26\x84\x57\xfd\xce\x34\x10\x63\x57\x9f\x0c\x0a\xa3" "\x02\xb0\x87\x36\xf5\xf8\x1e\x66\x81\x74\x2c\x3e\x90\xc0\x10\xf1" "\x53\xd4\xc3\x45\x9b\xe2\x58\xcf\x86\x2e\xf4\xb3\x11\xff\xe6\xc8" "\x5c\x74\x6e\xb4\xd9\x52\x2c\x52\x71\x5e\xb4\xf1\xca\xa7\x1c\x09" "\x6a\x2d\xc0\x20\x38\xf5\x61\xdc\xd9\x8d\x42\x71\x65\xf8\xce\xa7" "\xcb\x2c\x44\x09\x87\x5a\x02\xdd\x8c\xe1\xec\xd0\xe1\xeb\x4d\x25" "\x70\x57\xbd\xc7\x1b\xee\xb5\xc0\x81\xc5\x75\x45\xb8\xb7\xad\xfd" "\x33\xdc\xbe\x09\x71\xd0\xd4\xee\xf7\x37\x4e\x6f\x80\x5f\xec\x3f" "\x35\x75\x39\xaa\x41\xe6\x62\x17\xc5\x8f\xa4\xa7\x31\xd6\xd5\xe9" "\x56\xc2\xc7\x1d\xf1\x58\xf6\xad\x3b\xbc\xbe\x65\x12\xd4\xfb\xe2" "\x0a\x5a\x64\x9e\xad\x70\x1d\x95\xbd\x24\x1a\xa9\x99\xc0\x70\x74" "\xb1\x79\x01\x4f\xfd\x5d\x76\xa7\xd9\x53\x3d\x87\x2b\x51\xb4\xf3" "\x17\xa5\x41\xe9\x8b\xba\xd3\x69\xcd\xe6\x44\x0f\x18\x8f\x59\x0d" "\xb0\xb8\x2a\x7f\xbb\x16\x51\xf5\xe8\xad\xda\x66\xaa\x3a\xb6\x7d" "\x10\x13\x8d\xd9\x7d\x15\x09\x80\x7b\x00\x67\x96\x90\x21\x3e\xd4" "\x1a\xe8\x3b\x1c\x78\x31\x9b\x63\x64\xb9\x1b\x50\x11\x93\x48\x13" "\x89\xcb\xba\x57\x23\xcd\x95\x95\xd5\xee\x8b\x0d\xb4\xdf\x0c\x8a" "\xae\xae\x55\x3f\x93\xad\xc1\x3e\xe5\x31\x20\x73\x58\xb0\x0b\xba" "\xf5\x03\x7b\x50\x39\xa3\x66\xa9\x82\x47\x65\x29\xa8\x49\xd7\x5c" "\x51\x89\x97\x03\x31\x11\x75\x83\x6e\x4e\x80\x2d\x57\x93\x88\xec" "\x0e\x22\xa8\xde\x50\x99\x2c\xaa\xaf\x60\x3a\x74\xa0\x31\x16\x37" "\xcd\x8a\x4d\xda\x40\x1d\x0c\xf1\xc4\x7a\xd0\xaa\xf4\xa7\x55\xe3" "\xa4\xe3\x9d\x27\x4f\x81\xc6\x07\x74\x13\x8e\x4b\xd9\x6c\x33\xba" "\x28\x8d\xb7\x79\x36\x29\xfc\x98\x91\x29\x87\xe7\xf6\x92\xb8\x7c" "\xe4\xca\xb7\x21\x49\x8c\x01\x59\xad\x65\x37\x62\x9b\xba\x40\xc1" "\x79\x87\xe5\x48\x58\xe3\x0e\x3a\xda\x31\x03\x55\x36\x64\x00\xda" "\x61\x8a\x0a\x93\xdc\x82\xcc\x63\x40\xb5\x46\xde\xf0\x8c\x3f\x6d" "\x3e\x32\xf2\xe6\x1d\x37\xf0\xd1\x7e\x33\x52\xb6\x97\xc3\x80\x64" "\xa4\x0d\x5f\x97\xa5\xd8\xa3\x47\x1a\x83\x1f\xd0\x52\x81\xb9\xd9" "\x7a\x32\xe6\xf1\x3e\x7d\xdc\x01\x5d\xb8\x44\x12\xc0\x1f\x72\x72" "\x8b\x0e\xfa\x05\x37\x73\xbd\xc4\x06\x67\x18\xd7\xd4\x80\x2c\x2c" "\x13\x06\xfe\x82\x5b\x65\x88\xe3\x0b\x06\x3c\xe6\xe4\xd0\x8f\x24" "\x6a\x6a\x4d\x21\x4c\x2d\x05\x76\x12\xf9\xee\xbf\xb5\x5e\xcd\x03" "\xf0\x5b\x35\x82\xb7\x1d\x7b\xca\xa6\x14\x40\x68\xd2\xa5\x49\x34" "\x69\xb7\x05\x48\xf9\xdb\x93\xd4\x0b\x45\x8d\xb3\x1e\xa3\xf9\x5d" "\x8c\x18\xc5\x40\x14\x67\xc5\x40\xbe\x61\x53\x74\x52\x94\x6c\x5e" "\xc6\xdf\xd0\xe7\xe5\xbd\x4b\xca\x89\xca\xf6\xf4\xc5\x6f\xf6\x87" "\x9e\x3a\x11\x5a\xa8\xcd\x83\x70\x19\x63\x8a\xaf\x08\xb1\x33\xa9" "\x2a\xcc\xde\x7f\xd2\x63\xfb\x85\x40\x77\x40\x8f\x9d\xa0\x7c\xed" "\x8d\xe5\xe5\x31\x05\x75\xf2\x7e\xab\x22\x54\xbf\xfe\xd3\x1f\x45" "\x95\x0d\x6d\x07\x6a\x90\x06\xd6\x45\x97\xc0\x82\x88\xfc\xd8\xd0", "\xf1\xef\xf4\x8d\x9c\xfa\x92\x10\xd9\x4f\x22\x3f\x2f\x75\xe1\x8b" }, }; gcry_cipher_hd_t hde, hdd; unsigned char out[2048]; unsigned char tag[16]; int i, keylen; gcry_error_t err = 0; size_t pos, poslen, taglen2; int byteNum; if (verbose) fprintf (stderr, " Starting POLY1305 checks.\n"); for (i = 0; i < sizeof (tv) / sizeof (tv[0]); i++) { if (gcry_cipher_test_algo (tv[i].algo) && in_fips_mode) { if (verbose) fprintf (stderr, " algorithm %d not available in fips mode\n", tv[i].algo); continue; } if (verbose) fprintf (stderr, " checking POLY1305 mode for %s [%i]\n", gcry_cipher_algo_name (tv[i].algo), tv[i].algo); err = gcry_cipher_open (&hde, tv[i].algo, GCRY_CIPHER_MODE_POLY1305, 0); if (!err) err = gcry_cipher_open (&hdd, tv[i].algo, GCRY_CIPHER_MODE_POLY1305, 0); if (err) { fail ("poly1305, gcry_cipher_open failed: %s\n", gpg_strerror (err)); return; } keylen = gcry_cipher_get_algo_keylen(tv[i].algo); if (!keylen) { fail ("poly1305, gcry_cipher_get_algo_keylen failed\n"); return; } err = gcry_cipher_setkey (hde, tv[i].key, keylen); if (!err) err = gcry_cipher_setkey (hdd, tv[i].key, keylen); if (err) { fail ("poly1305, gcry_cipher_setkey failed: %s\n", gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } err = gcry_cipher_setiv (hde, tv[i].iv, tv[i].ivlen); if (!err) err = gcry_cipher_setiv (hdd, tv[i].iv, tv[i].ivlen); if (err) { fail ("poly1305, gcry_cipher_setiv failed: %s\n", gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } err = gcry_cipher_info (hde, GCRYCTL_GET_TAGLEN, NULL, &taglen2); if (err) { fail ("cipher-poly1305, gcryctl_get_taglen failed (tv %d): %s\n", i, gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } if (taglen2 != 16) { fail ("cipher-poly1305, gcryctl_get_taglen returned bad length" " (tv %d): got=%zu want=%d\n", i, taglen2, 16); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } for (pos = 0; pos < tv[i].aadlen; pos += step) { poslen = (pos + step < tv[i].aadlen) ? step : tv[i].aadlen - pos; err = gcry_cipher_authenticate(hde, tv[i].aad + pos, poslen); if (err) { fail ("poly1305, gcry_cipher_authenticate (%d) (%lu:%d) failed: " "%s\n", i, (unsigned long) pos, step, gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } err = gcry_cipher_authenticate(hdd, tv[i].aad + pos, poslen); if (err) { fail ("poly1305, de gcry_cipher_authenticate (%d) (%lu:%d) failed: " "%s\n", i, (unsigned long) pos, step, gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } } for (pos = 0; pos < tv[i].inlen; pos += step) { poslen = (pos + step < tv[i].inlen) ? step : tv[i].inlen - pos; err = gcry_cipher_encrypt (hde, out + pos, poslen, tv[i].plaintext + pos, poslen); if (err) { fail ("poly1305, gcry_cipher_encrypt (%d) (%lu:%d) failed: %s\n", i, (unsigned long) pos, step, gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } } if (memcmp (tv[i].out, out, tv[i].inlen)) fail ("poly1305, encrypt mismatch entry %d (step %d)\n", i, step); for (pos = 0; pos < tv[i].inlen; pos += step) { poslen = (pos + step < tv[i].inlen) ? step : tv[i].inlen - pos; err = gcry_cipher_decrypt (hdd, out + pos, poslen, NULL, 0); if (err) { fail ("poly1305, gcry_cipher_decrypt (%d) (%lu:%d) failed: %s\n", i, (unsigned long) pos, step, gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } } if (memcmp (tv[i].plaintext, out, tv[i].inlen)) fail ("poly1305, decrypt mismatch entry %d (step %d)\n", i, step); err = gcry_cipher_gettag (hde, out, 16); if (err) { fail ("poly1305, gcry_cipher_gettag(%d) failed: %s\n", i, gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } if (memcmp (tv[i].tag, out, 16)) fail ("poly1305, encrypt tag mismatch entry %d\n", i); err = gcry_cipher_checktag (hdd, out, 16); if (err) { fail ("poly1305, gcry_cipher_checktag(%d) failed: %s\n", i, gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } err = gcry_cipher_reset(hde); if (!err) err = gcry_cipher_reset(hdd); if (err) { fail ("poly1305, gcry_cipher_reset (%d) failed: %s\n", i, gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } /* gcry_cipher_reset clears the IV */ err = gcry_cipher_setiv (hde, tv[i].iv, tv[i].ivlen); if (!err) err = gcry_cipher_setiv (hdd, tv[i].iv, tv[i].ivlen); if (err) { fail ("poly1305, gcry_cipher_setiv failed: %s\n", gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } /* this time we authenticate, encrypt and decrypt one byte at a time */ for (byteNum = 0; byteNum < tv[i].aadlen; ++byteNum) { err = gcry_cipher_authenticate(hde, tv[i].aad + byteNum, 1); if (err) { fail ("poly1305, gcry_cipher_authenticate (%d) (byte-buf) failed: " "%s\n", i, gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } err = gcry_cipher_authenticate(hdd, tv[i].aad + byteNum, 1); if (err) { fail ("poly1305, de gcry_cipher_authenticate (%d) (byte-buf) " "failed: %s\n", i, gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } } for (byteNum = 0; byteNum < tv[i].inlen; ++byteNum) { err = gcry_cipher_encrypt (hde, out+byteNum, 1, (tv[i].plaintext) + byteNum, 1); if (err) { fail ("poly1305, gcry_cipher_encrypt (%d) (byte-buf) failed: %s\n", i, gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } } if (memcmp (tv[i].out, out, tv[i].inlen)) fail ("poly1305, encrypt mismatch entry %d, (byte-buf)\n", i); err = gcry_cipher_gettag (hde, tag, 16); if (err) { fail ("poly1305, gcry_cipher_gettag(%d) (byte-buf) failed: %s\n", i, gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } if (memcmp (tv[i].tag, tag, 16)) fail ("poly1305, encrypt tag mismatch entry %d, (byte-buf)\n", i); for (byteNum = 0; byteNum < tv[i].inlen; ++byteNum) { err = gcry_cipher_decrypt (hdd, out+byteNum, 1, NULL, 0); if (err) { fail ("poly1305, gcry_cipher_decrypt (%d) (byte-buf) failed: %s\n", i, gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } } if (memcmp (tv[i].plaintext, out, tv[i].inlen)) fail ("poly1305, decrypt mismatch entry %d\n", i); err = gcry_cipher_checktag (hdd, tag, 16); if (err) { fail ("poly1305, gcry_cipher_checktag(%d) (byte-buf) failed: %s\n", i, gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } gcry_cipher_close (hde); gcry_cipher_close (hdd); } if (verbose) fprintf (stderr, " Completed POLY1305 checks.\n"); } static void check_poly1305_cipher (void) { /* Large buffers, no splitting. */ _check_poly1305_cipher(0xffffffff); /* Split input to one byte buffers. */ _check_poly1305_cipher(1); /* Split input to 7 byte buffers. */ _check_poly1305_cipher(7); /* Split input to 16 byte buffers. */ _check_poly1305_cipher(16); } static void check_ccm_cipher (void) { static const struct tv { int algo; int 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 += 16) { unsigned char hash[20]; unsigned char ctr[4]; ctr[0] = (i >> 0) & 0xff; ctr[1] = (i >> 8) & 0xff; ctr[2] = (i >> 16) & 0xff; ctr[3] = (i >> 24) & 0xff; gcry_md_hash_buffer (GCRY_MD_SHA1, hash, ctr, sizeof(ctr)); memcpy(inbuf + i, hash, 16); } if (gcry_cipher_test_algo (algo) && in_fips_mode) { if (verbose) fprintf (stderr, " algorithm %d not available in fips mode\n", algo); goto out_free; } err = gcry_cipher_open (&hde, algo, GCRY_CIPHER_MODE_OCB, 0); if (!err) err = gcry_cipher_open (&hdd, algo, GCRY_CIPHER_MODE_OCB, 0); if (err) { fail ("cipher-ocb, gcry_cipher_open failed (large, algo %d): %s\n", algo, gpg_strerror (err)); goto out_free; } err = gcry_cipher_setkey (hde, key, keylen); if (!err) err = gcry_cipher_setkey (hdd, key, keylen); if (err) { fail ("cipher-ocb, gcry_cipher_setkey failed (large, algo %d): %s\n", algo, gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); goto out_free; } err = gcry_cipher_setiv (hde, nonce, 12); if (!err) err = gcry_cipher_setiv (hdd, nonce, 12); if (err) { fail ("cipher-ocb, gcry_cipher_setiv failed (large, algo %d): %s\n", algo, gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); goto out_free; } if (splitpos) { err = gcry_cipher_authenticate (hde, inbuf, splitpos); } if (!err) { err = gcry_cipher_authenticate (hde, inbuf + splitpos, buflen - splitpos); } if (err) { fail ("cipher-ocb, gcry_cipher_authenticate failed (large, algo %d): %s\n", algo, gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); goto out_free; } if (splitpos) { err = gcry_cipher_encrypt (hde, outbuf, splitpos, inbuf, splitpos); } if (!err) { err = gcry_cipher_final (hde); if (!err) { err = gcry_cipher_encrypt (hde, outbuf + splitpos, buflen - splitpos, inbuf + splitpos, buflen - splitpos); } } if (err) { fail ("cipher-ocb, gcry_cipher_encrypt failed (large, algo %d): %s\n", algo, gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); goto out_free; } /* Check that the tag matches. */ err = gcry_cipher_gettag (hde, tag, 16); if (err) { fail ("cipher_ocb, gcry_cipher_gettag failed (large, algo %d): %s\n", algo, gpg_strerror (err)); } if (memcmp (tagexpect, tag, 16)) { mismatch (tagexpect, 16, tag, 16); fail ("cipher-ocb, encrypt tag mismatch (large, algo %d)\n", algo); } err = gcry_cipher_authenticate (hdd, inbuf, buflen); if (err) { fail ("cipher-ocb, gcry_cipher_authenticate failed (large, algo %d): %s\n", algo, gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); goto out_free; } /* Now for the decryption. */ if (splitpos) { err = gcry_cipher_decrypt (hdd, outbuf, splitpos, NULL, 0); } if (!err) { err = gcry_cipher_final (hdd); if (!err) { err = gcry_cipher_decrypt (hdd, outbuf + splitpos, buflen - splitpos, NULL, 0); } } if (err) { fail ("cipher-ocb, gcry_cipher_decrypt (large, algo %d) failed: %s\n", algo, gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); goto out_free; } /* We still have TAG from the encryption. */ err = gcry_cipher_checktag (hdd, tag, 16); if (err) { fail ("cipher-ocb, gcry_cipher_checktag failed (large, algo %d): %s\n", algo, gpg_strerror (err)); } /* Check that the decrypt output matches the original plaintext. */ if (memcmp (inbuf, outbuf, buflen)) { /*mismatch (inbuf, buflen, outbuf, buflen);*/ fail ("cipher-ocb, decrypt data mismatch (large, algo %d)\n", algo); } /* Check that gettag also works for decryption. */ err = gcry_cipher_gettag (hdd, tag, 16); if (err) { fail ("cipher_ocb, decrypt gettag failed (large, algo %d): %s\n", algo, gpg_strerror (err)); } if (memcmp (tagexpect, tag, 16)) { mismatch (tagexpect, 16, tag, 16); fail ("cipher-ocb, decrypt tag mismatch (large, algo %d)\n", algo); } gcry_cipher_close (hde); gcry_cipher_close (hdd); out_free: xfree(outbuf); xfree(inbuf); } static void check_ocb_cipher_checksum (int algo, int keylen) { static const unsigned char key[32] = "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F" "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F"; static const unsigned char nonce[12] = "\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x00\x01\x02\x03"; const size_t buflen = 128 * 16; unsigned char *inbuf, *outbuf; gpg_error_t err = 0; gcry_cipher_hd_t hde, hde2, hdd; unsigned char tag[16]; unsigned char tag2[16]; unsigned char tag3[16]; int i; inbuf = xmalloc(buflen); if (!inbuf) { fail ("out-of-memory\n"); return; } outbuf = xmalloc(buflen); if (!inbuf) { fail ("out-of-memory\n"); xfree(inbuf); return; } memset(inbuf, 0, buflen); for (i = 0; i < 128; i += 16) { unsigned char *blk = inbuf + i; int bit2set = i / 16; int byteidx = bit2set / 8; int bitpos = bit2set % 8; blk[byteidx] |= 1 << bitpos; } if (gcry_cipher_test_algo (algo) && in_fips_mode) { if (verbose) fprintf (stderr, " algorithm %d not available in fips mode\n", algo); goto out_free; } err = gcry_cipher_open (&hde, algo, GCRY_CIPHER_MODE_OCB, 0); if (!err) err = gcry_cipher_open (&hde2, algo, GCRY_CIPHER_MODE_OCB, 0); if (!err) err = gcry_cipher_open (&hdd, algo, GCRY_CIPHER_MODE_OCB, 0); if (err) { fail ("cipher-ocb, gcry_cipher_open failed (checksum, algo %d): %s\n", algo, gpg_strerror (err)); goto out_free; } err = gcry_cipher_setkey (hde, key, keylen); if (!err) err = gcry_cipher_setkey (hde2, key, keylen); if (!err) err = gcry_cipher_setkey (hdd, key, keylen); if (err) { fail ("cipher-ocb, gcry_cipher_setkey failed (checksum, algo %d): %s\n", algo, gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hde2); gcry_cipher_close (hdd); goto out_free; } err = gcry_cipher_setiv (hde, nonce, 12); if (!err) err = gcry_cipher_setiv (hde2, nonce, 12); if (!err) err = gcry_cipher_setiv (hdd, nonce, 12); if (err) { fail ("cipher-ocb, gcry_cipher_setiv failed (checksum, algo %d): %s\n", algo, gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hde2); gcry_cipher_close (hdd); goto out_free; } err = gcry_cipher_final (hde); if (!err) { err = gcry_cipher_encrypt (hde, outbuf, buflen, inbuf, buflen); } for (i = 0; i < buflen && !err; i += 16) { if (i + 16 == buflen) err = gcry_cipher_final (hde2); if (!err) err = gcry_cipher_encrypt (hde2, outbuf + i, 16, inbuf + i, 16); } if (!err) { err = gcry_cipher_final (hdd); } if (!err) { err = gcry_cipher_decrypt (hdd, outbuf, buflen, outbuf, buflen); } if (err) { fail ("cipher-ocb, gcry_cipher_encrypt failed (checksum, algo %d): %s\n", algo, gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hde2); gcry_cipher_close (hdd); goto out_free; } /* Check that the tag matches. */ err = gcry_cipher_gettag (hde, tag, 16); if (err) { fail ("cipher_ocb, gcry_cipher_gettag failed (checksum, algo %d): %s\n", algo, gpg_strerror (err)); } err = gcry_cipher_gettag (hde2, tag2, 16); if (err) { fail ("cipher_ocb, gcry_cipher_gettag failed (checksum2, algo %d): %s\n", algo, gpg_strerror (err)); } err = gcry_cipher_gettag (hdd, tag3, 16); if (err) { fail ("cipher_ocb, gcry_cipher_gettag failed (checksum3, algo %d): %s\n", algo, gpg_strerror (err)); } if (memcmp (tag, tag2, 16)) { mismatch (tag, 16, tag2, 16); fail ("cipher-ocb, encrypt tag mismatch (checksum, algo %d)\n", algo); } if (memcmp (tag, tag3, 16)) { mismatch (tag, 16, tag3, 16); fail ("cipher-ocb, decrypt tag mismatch (checksum, algo %d)\n", algo); } gcry_cipher_close (hde); gcry_cipher_close (hde2); gcry_cipher_close (hdd); out_free: xfree(inbuf); xfree(outbuf); } static void check_ocb_cipher_largebuf (int algo, int keylen, const char *tagexpect) { unsigned int split; for (split = 0; split < 32 * 16; split = split * 2 + 16) { check_ocb_cipher_largebuf_split(algo, keylen, tagexpect, split); } check_ocb_cipher_checksum(algo, keylen); } static void check_ocb_cipher_splitaad (void) { const char t_nonce[] = ("BBAA9988776655443322110D"); const char t_plain[] = ("000102030405060708090A0B0C0D0E0F1011121314151617" "18191A1B1C1D1E1F2021222324252627"); const char t_ciph[] = ("D5CA91748410C1751FF8A2F618255B68A0A12E093FF45460" "6E59F9C1D0DDC54B65E8628E568BAD7AED07BA06A4A69483" "A7035490C5769E60"); struct { const char *aad0; const char *aad1; const char *aad2; const char *aad3; } tv[] = { { "000102030405060708090A0B0C0D0E0F" "101112131415161718191A1B1C1D1E1F2021222324252627" }, { "000102030405060708090A0B0C0D0E0F", "101112131415161718191A1B1C1D1E1F", "2021222324252627" }, { "000102030405060708090A0B0C0D0E0F", "1011121314151617", "18191A1B1C1D1E1F", "2021222324252627" }, { "000102030405060708090A0B0C0D0E0F", "101112131415161718191A1B1C1D1E1F", "20", "21222324252627" }, { "000102030405060708090A0B0C0D0E0F", "101112131415161718191A1B1C1D1E1F", "2021", "222324252627" }, { "000102030405060708090A0B0C0D0E0F", "101112131415161718191A1B1C1D1E1F", "202122", "2324252627" }, { "000102030405060708090A0B0C0D0E0F", "101112131415161718191A1B1C1D1E1F", "20212223", "24252627" }, { "000102030405060708090A0B0C0D0E0F", "101112131415161718191A1B1C1D1E1F", "2021222324", "252627" }, { "000102030405060708090A0B0C0D0E0F", "101112131415161718191A1B1C1D1E1F", "202122232425", "2627" }, { "000102030405060708090A0B0C0D0E0F", "101112131415161718191A1B1C1D1E1F", "20212223242526" "27" }, { "000102030405060708090A0B0C0D0E0F", "1011121314151617", "18191A1B1C1D1E1F2021222324252627" }, { "00", "0102030405060708090A0B0C0D0E0F", "1011121314151617", "18191A1B1C1D1E1F2021222324252627" }, { "0001", "02030405060708090A0B0C0D0E0F", "1011121314151617", "18191A1B1C1D1E1F2021222324252627" }, { "000102030405060708090A0B0C0D", "0E0F", "1011121314151617", "18191A1B1C1D1E1F2021222324252627" }, { "000102030405060708090A0B0C0D0E", "0F", "1011121314151617", "18191A1B1C1D1E1F2021222324252627" }, { "000102030405060708090A0B0C0D0E", "0F101112131415161718191A1B1C1D1E1F20212223242526", "27" } }; gpg_error_t err = 0; gcry_cipher_hd_t hde; unsigned char out[MAX_DATA_LEN]; unsigned char tag[16]; int tidx; char *key, *nonce, *ciph, *plain; size_t keylen, noncelen, ciphlen, plainlen; int i; /* Convert to hex strings to binary. */ key = hex2buffer ("000102030405060708090A0B0C0D0E0F", &keylen); nonce = hex2buffer (t_nonce, &noncelen); plain = hex2buffer (t_plain, &plainlen); ciph = hex2buffer (t_ciph, &ciphlen); /* Check that our test vectors are sane. */ assert (plainlen <= sizeof out); assert (16 <= ciphlen); assert (16 <= sizeof tag); for (tidx = 0; tidx < DIM (tv); tidx++) { char *aad[4]; size_t aadlen[4]; if (verbose) fprintf (stderr, " checking OCB aad split (tv %d)\n", tidx); aad[0] = tv[tidx].aad0? hex2buffer (tv[tidx].aad0, aadlen+0) : NULL; aad[1] = tv[tidx].aad1? hex2buffer (tv[tidx].aad1, aadlen+1) : NULL; aad[2] = tv[tidx].aad2? hex2buffer (tv[tidx].aad2, aadlen+2) : NULL; aad[3] = tv[tidx].aad3? hex2buffer (tv[tidx].aad3, aadlen+3) : NULL; err = gcry_cipher_open (&hde, GCRY_CIPHER_AES, GCRY_CIPHER_MODE_OCB, 0); if (err) { fail ("cipher-ocb-splitadd, gcry_cipher_open failed: %s\n", gpg_strerror (err)); return; } err = gcry_cipher_setkey (hde, key, keylen); if (err) { fail ("cipher-ocb-splitaad, gcry_cipher_setkey failed: %s\n", gpg_strerror (err)); gcry_cipher_close (hde); return; } err = gcry_cipher_setiv (hde, nonce, noncelen); if (err) { fail ("cipher-ocb-splitaad, gcry_cipher_setiv failed: %s\n", gpg_strerror (err)); gcry_cipher_close (hde); return; } for (i=0; i < DIM (aad); i++) { if (!aad[i]) continue; err = gcry_cipher_authenticate (hde, aad[i], aadlen[i]); if (err) { fail ("cipher-ocb-splitaad," " gcry_cipher_authenticate failed (tv=%d,i=%d): %s\n", tidx, i, gpg_strerror (err)); gcry_cipher_close (hde); return; } } err = gcry_cipher_final (hde); if (!err) err = gcry_cipher_encrypt (hde, out, MAX_DATA_LEN, plain, plainlen); if (err) { fail ("cipher-ocb-splitaad, gcry_cipher_encrypt failed: %s\n", gpg_strerror (err)); gcry_cipher_close (hde); return; } /* Check that the encrypt output matches the expected cipher text without the tag (i.e. at the length of plaintext). */ if (memcmp (ciph, out, plainlen)) { mismatch (ciph, plainlen, out, plainlen); fail ("cipher-ocb-splitaad, encrypt data mismatch\n"); } /* Check that the tag matches TAGLEN bytes from the end of the expected ciphertext. */ err = gcry_cipher_gettag (hde, tag, 16); if (err) { fail ("cipher-ocb-splitaad, gcry_cipher_gettag failed: %s\n", gpg_strerror (err)); } if (memcmp (ciph + ciphlen - 16, tag, 16)) { mismatch (ciph + ciphlen - 16, 16, tag, 16); fail ("cipher-ocb-splitaad, encrypt tag mismatch\n"); } gcry_cipher_close (hde); xfree (aad[0]); xfree (aad[1]); xfree (aad[2]); xfree (aad[3]); } xfree (nonce); xfree (ciph); xfree (plain); xfree (key); } static void check_ocb_cipher (void) { /* Check OCB cipher with separate destination and source buffers for * encryption/decryption. */ do_check_ocb_cipher(0); /* Check OCB cipher with inplace encrypt/decrypt. */ do_check_ocb_cipher(1); /* Check large buffer encryption/decryption. */ check_ocb_cipher_largebuf(GCRY_CIPHER_AES, 16, "\x4a\x00\x7f\x8d\xbe\x38\x32\x48\xb2\x2f\x7f\x27\xd8\x15\x7f\xb0"); check_ocb_cipher_largebuf(GCRY_CIPHER_AES256, 32, "\xec\xc5\xe9\x2b\x24\x91\xba\x64\xbc\xe3\x62\xb6\x83\x20\xad\xbd"); check_ocb_cipher_largebuf(GCRY_CIPHER_CAMELLIA128, 16, "\xd5\xbd\x76\xec\x75\x4a\xab\x6c\x13\xec\x87\x95\x11\xd4\xf0\x3d"); check_ocb_cipher_largebuf(GCRY_CIPHER_CAMELLIA192, 24, "\xde\xdd\x6b\xbf\xce\x15\x01\x39\x7c\xc5\x69\x19\x72\xa2\x67\x23"); check_ocb_cipher_largebuf(GCRY_CIPHER_CAMELLIA256, 32, "\x0c\xf3\xd5\x82\x20\x73\xee\x0f\xbd\x6b\x32\x38\xf9\x10\xef\xe5"); check_ocb_cipher_largebuf(GCRY_CIPHER_TWOFISH, 16, "\x54\x87\x68\xb6\x17\xe6\xd7\xa6\x76\x0d\x7e\x9f\x57\x8b\xec\x88"); check_ocb_cipher_largebuf(GCRY_CIPHER_TWOFISH, 32, "\x0b\xc3\x93\x52\xfa\x97\x22\xe6\x88\x6e\x29\x4d\x77\x35\x48\x84"); check_ocb_cipher_largebuf(GCRY_CIPHER_SERPENT128, 16, "\x7e\x49\x3b\xd6\xde\x6e\x9e\x53\x67\xcd\x00\xad\xc9\xd9\xa5\xbc"); check_ocb_cipher_largebuf(GCRY_CIPHER_SERPENT192, 24, "\x1e\x33\x0e\x06\xc8\x27\x6a\x0b\x41\x5e\x93\xae\x39\xf4\x50\x12"); check_ocb_cipher_largebuf(GCRY_CIPHER_SERPENT256, 32, "\x6b\x4c\x3f\x8f\x77\x75\xf2\x4d\xaf\xde\x2c\x5f\x1a\x80\xb8\x4d"); check_ocb_cipher_largebuf(GCRY_CIPHER_SM4, 16, "\x3c\x32\x54\x5d\xc5\x17\xa1\x16\x3f\x8e\xc7\x1d\x8d\x8b\x2d\xb0"); /* Check that the AAD data is correctly buffered. */ check_ocb_cipher_splitaad (); } static void do_check_xts_cipher (int inplace) { /* Note that we use hex strings and not binary strings in TV. That makes it easier to maintain the test vectors. */ static const struct { int algo; const char *key; /* NULL means "000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F" */ const char *iv; const char *plain; const char *ciph; } tv[] = { /* CAVS; hex/XTSGenAES128.rsp; COUNT=100 */ { GCRY_CIPHER_AES, "bcb6613c495de4bdad9c19f04e4b3915f9ecb379e1a575b633337e934fca1050", "64981173159d58ac355a20120c8e81f1", "189acacee06dfa7c94484c7dae59e166", "7900191d0f19a97668fdba9def84eedc" }, /* CAVS; hex/XTSGenAES128.rsp; COUNT=101 */ { GCRY_CIPHER_AES, "b7b93f516aef295eff3a29d837cf1f135347e8a21dae616ff5062b2e8d78ce5e", "873edea653b643bd8bcf51403197ed14", "236f8a5b58dd55f6194ed70c4ac1a17f1fe60ec9a6c454d087ccb77d6b638c47", "22e6a3c6379dcf7599b052b5a749c7f78ad8a11b9f1aa9430cf3aef445682e19" }, /* CAVS; hex/XTSGenAES128.rsp; COUNT=301 */ { GCRY_CIPHER_AES, "394c97881abd989d29c703e48a72b397a7acf51b59649eeea9b33274d8541df4", "4b15c684a152d485fe9937d39b168c29", "2f3b9dcfbae729583b1d1ffdd16bb6fe2757329435662a78f0", "f3473802e38a3ffef4d4fb8e6aa266ebde553a64528a06463e" }, /* CAVS; hex/XTSGenAES128.rsp; COUNT=500 */ { GCRY_CIPHER_AES, "783a83ec52a27405dff9de4c57f9c979b360b6a5df88d67ec1a052e6f582a717", "886e975b29bdf6f0c01bb47f61f6f0f5", "b04d84da856b9a59ce2d626746f689a8051dacd6bce3b990aa901e4030648879", "f941039ebab8cac39d59247cbbcb4d816c726daed11577692c55e4ac6d3e6820" }, /* CAVS; hex/XTSGenAES256.rsp; COUNT=1 */ { GCRY_CIPHER_AES256, "1ea661c58d943a0e4801e42f4b0947149e7f9f8e3e68d0c7505210bd311a0e7c" "d6e13ffdf2418d8d1911c004cda58da3d619b7e2b9141e58318eea392cf41b08", "adf8d92627464ad2f0428e84a9f87564", "2eedea52cd8215e1acc647e810bbc3642e87287f8d2e57e36c0a24fbc12a202e", "cbaad0e2f6cea3f50b37f934d46a9b130b9d54f07e34f36af793e86f73c6d7db" }, /* CAVS; hex/XTSGenAES256.rsp; COUNT=101 */ { GCRY_CIPHER_AES256, "266c336b3b01489f3267f52835fd92f674374b88b4e1ebd2d36a5f457581d9d0" "42c3eef7b0b7e5137b086496b4d9e6ac658d7196a23f23f036172fdb8faee527", "06b209a7a22f486ecbfadb0f3137ba42", "ca7d65ef8d3dfad345b61ccddca1ad81de830b9e86c7b426d76cb7db766852d9" "81c6b21409399d78f42cc0b33a7bbb06", "c73256870cc2f4dd57acc74b5456dbd776912a128bc1f77d72cdebbf270044b7" "a43ceed29025e1e8be211fa3c3ed002d" }, /* CAVS; hex/XTSGenAES256.rsp; COUNT=401 */ { GCRY_CIPHER_AES256, "33e89e817ff8d037d6ac5a2296657503f20885d94c483e26449066bd9284d130" "2dbdbb4b66b6b9f4687f13dd028eb6aa528ca91deb9c5f40db93218806033801", "a78c04335ab7498a52b81ed74b48e6cf", "14c3ac31291b075f40788247c3019e88c7b40bac3832da45bbc6c4fe7461371b" "4dfffb63f71c9f8edb98f28ff4f33121", "dead7e587519bc78c70d99279fbe3d9b1ad13cdaae69824e0ab8135413230bfd" "b13babe8f986fbb30d46ab5ec56b916e" }, /* From https://github.com/heisencoder/XTS-AES/blob/master/testvals/ */ { GCRY_CIPHER_AES, "fffefdfcfbfaf9f8f7f6f5f4f3f2f1f0fffefdfcfbfaf9f8f7f6f5f4f3f2f1f0", "9a785634120000000000000000000000", "000102030405060708090a0b0c0d0e0f10", "7fb2e8beccbb5c118aa52ddca31220bb1b" }, { GCRY_CIPHER_AES, "fffefdfcfbfaf9f8f7f6f5f4f3f2f1f0bfbebdbcbbbab9b8b7b6b5b4b3b2b1b0", "9a785634120000000000000000000000", "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e", "d05bc090a8e04f1b3d3ecdd5baec0fd4edbf9dace45d6f6a7306e64be5dd82" }, { GCRY_CIPHER_AES, "2718281828459045235360287471352631415926535897932384626433832795", "00000000000000000000000000000000", "000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F" "20212223", "27A7479BEFA1D476489F308CD4CFA6E288F548E5C4239F91712A587E2B05AC3D" "A96E4BBE" }, { GCRY_CIPHER_AES256, "2718281828459045235360287471352662497757247093699959574966967627" "3141592653589793238462643383279502884197169399375105820974944592", "11000000000000000000000000000000", "3A060A8CAD115A6F44572E3759E43C8F8832FEDC28A8E35B357B5CF3EDBEF788" "CAD8BFCB23", "6D1C78A8BAD91DB2924C507CCEDE835F5BADD157DA0AF55C98BBC28CF676F9FA" "61618FA696" }, { GCRY_CIPHER_AES256, "2718281828459045235360287471352662497757247093699959574966967627" "3141592653589793238462643383279502884197169399375105820974944592", "11000000000000000000000000000000", "3A060A8CAD115A6F44572E3759E43C8F8832FEDC28A8E35B357B5CF3EDBEF788" "CAD8BFCB23", "6D1C78A8BAD91DB2924C507CCEDE835F5BADD157DA0AF55C98BBC28CF676F9FA" "61618FA696" }, { GCRY_CIPHER_AES, "e0e1e2e3e4e5e6e7e8e9eaebecedeeefc0c1c2c3c4c5c6c7c8c9cacbcccdcecf", "21436587a90000000000000000000000", "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f" "202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f" "404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f" "606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f" "808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f" "a0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebf" "c0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedf" "e0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff" "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f" "202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f" "404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f" "606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f" "808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f" "a0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebf" "c0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedf" "e0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff" "0001020304050607", "38b45812ef43a05bd957e545907e223b954ab4aaf088303ad910eadf14b42be6" "8b2461149d8c8ba85f992be970bc621f1b06573f63e867bf5875acafa04e42cc" "bd7bd3c2a0fb1fff791ec5ec36c66ae4ac1e806d81fbf709dbe29e471fad3854" "9c8e66f5345d7c1eb94f405d1ec785cc6f6a68f6254dd8339f9d84057e01a177" "41990482999516b5611a38f41bb6478e6f173f320805dd71b1932fc333cb9ee3" "9936beea9ad96fa10fb4112b901734ddad40bc1878995f8e11aee7d141a2f5d4" "8b7a4e1e7f0b2c04830e69a4fd1378411c2f287edf48c6c4e5c247a19680f7fe" "41cefbd49b582106e3616cbbe4dfb2344b2ae9519391f3e0fb4922254b1d6d2d" "19c6d4d537b3a26f3bcc51588b32f3eca0829b6a5ac72578fb814fb43cf80d64" "a233e3f997a3f02683342f2b33d25b492536b93becb2f5e1a8b82f5b88334272" "9e8ae09d16938841a21a97fb543eea3bbff59f13c1a18449e398701c1ad51648" "346cbc04c27bb2da3b93a1372ccae548fb53bee476f9e9c91773b1bb19828394" "d55d3e1a20ed69113a860b6829ffa847224604435070221b257e8dff783615d2" "cae4803a93aa4334ab482a0afac9c0aeda70b45a481df5dec5df8cc0f423c77a" "5fd46cd312021d4b438862419a791be03bb4d97c0e59578542531ba466a83baf" "92cefc151b5cc1611a167893819b63fb37ec662bc0fc907db74a94468a55a7bc" "8a6b18e86de60290" }, { GCRY_CIPHER_AES256, "2718281828459045235360287471352662497757247093699959574966967627" "3141592653589793238462643383279502884197169399375105820974944592", "ffffffff000000000000000000000000", "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f" "202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f" "404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f" "606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f" "808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f" "a0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebf" "c0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedf" "e0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff" "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f" "202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f" "404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f" "606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f" "808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f" "a0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebf" "c0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedf" "e0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff", "bf53d2dade78e822a4d949a9bc6766b01b06a8ef70d26748c6a7fc36d80ae4c5" "520f7c4ab0ac8544424fa405162fef5a6b7f229498063618d39f0003cb5fb8d1" "c86b643497da1ff945c8d3bedeca4f479702a7a735f043ddb1d6aaade3c4a0ac" "7ca7f3fa5279bef56f82cd7a2f38672e824814e10700300a055e1630b8f1cb0e" "919f5e942010a416e2bf48cb46993d3cb6a51c19bacf864785a00bc2ecff15d3" "50875b246ed53e68be6f55bd7e05cfc2b2ed6432198a6444b6d8c247fab941f5" "69768b5c429366f1d3f00f0345b96123d56204c01c63b22ce78baf116e525ed9" "0fdea39fa469494d3866c31e05f295ff21fea8d4e6e13d67e47ce722e9698a1c" "1048d68ebcde76b86fcf976eab8aa9790268b7068e017a8b9b749409514f1053" "027fd16c3786ea1bac5f15cb79711ee2abe82f5cf8b13ae73030ef5b9e4457e7" "5d1304f988d62dd6fc4b94ed38ba831da4b7634971b6cd8ec325d9c61c00f1df" "73627ed3745a5e8489f3a95c69639c32cd6e1d537a85f75cc844726e8a72fc00" "77ad22000f1d5078f6b866318c668f1ad03d5a5fced5219f2eabbd0aa5c0f460" "d183f04404a0d6f469558e81fab24a167905ab4c7878502ad3e38fdbe62a4155" "6cec37325759533ce8f25f367c87bb5578d667ae93f9e2fd99bcbc5f2fbba88c" "f6516139420fcff3b7361d86322c4bd84c82f335abb152c4a93411373aaa8220" } }; gpg_error_t err = 0; gcry_cipher_hd_t hde, hdd; int tidx; int got_err = 0; if (verbose) fprintf (stderr, " Starting XTS checks.\n"); for (tidx = 0; !got_err && tidx < DIM (tv); tidx++) { const char *hexkey = tv[tidx].key; char *key, *iv, *ciph, *plain, *out; size_t keylen, ivlen, ciphlen, plainlen, outlen; if (verbose) fprintf (stderr, " checking XTS mode for %s [%i] (tv %d)\n", gcry_cipher_algo_name (tv[tidx].algo), tv[tidx].algo, tidx); if (!hexkey) hexkey = "000102030405060708090A0B0C0D0E0F" "101112131415161718191A1B1C1D1E1F"; /* Convert to hex strings to binary. */ key = hex2buffer (hexkey, &keylen); iv = hex2buffer (tv[tidx].iv, &ivlen); plain = hex2buffer (tv[tidx].plain, &plainlen); ciph = hex2buffer (tv[tidx].ciph, &ciphlen); outlen = plainlen + 5; out = xmalloc (outlen); assert (plainlen == ciphlen); assert (plainlen <= outlen); assert (out); err = gcry_cipher_open (&hde, tv[tidx].algo, GCRY_CIPHER_MODE_XTS, 0); if (!err) err = gcry_cipher_open (&hdd, tv[tidx].algo, GCRY_CIPHER_MODE_XTS, 0); if (err) { fail ("cipher-xts, gcry_cipher_open failed (tv %d): %s\n", tidx, gpg_strerror (err)); return; } err = gcry_cipher_setkey (hde, key, keylen); if (err && in_fips_mode && memcmp(key, key + keylen/2, keylen/2) == 0) { /* Since both halves of key are the same, fail to set key in FIPS mode is expected. */ goto next_tv; } if (!err) err = gcry_cipher_setkey (hdd, key, keylen); if (err) { fail ("cipher-xts, gcry_cipher_setkey failed (tv %d): %s\n", tidx, gpg_strerror (err)); goto err_out; } err = gcry_cipher_setiv (hde, iv, ivlen); if (!err) err = gcry_cipher_setiv (hdd, iv, ivlen); if (err) { fail ("cipher-xts, gcry_cipher_setiv failed (tv %d): %s\n", tidx, gpg_strerror (err)); goto err_out; } if (inplace) { memcpy(out, plain, plainlen); err = gcry_cipher_encrypt (hde, out, plainlen, NULL, 0); } else { err = gcry_cipher_encrypt (hde, out, outlen, plain, plainlen); } if (err) { fail ("cipher-xts, gcry_cipher_encrypt failed (tv %d): %s\n", tidx, gpg_strerror (err)); goto err_out; } /* Check that the encrypt output matches the expected cipher text. */ if (memcmp (ciph, out, plainlen)) { mismatch (ciph, plainlen, out, plainlen); fail ("cipher-xts, encrypt data mismatch (tv %d)\n", tidx); } /* Now for the decryption. */ if (inplace) { err = gcry_cipher_decrypt (hdd, out, plainlen, NULL, 0); } else { memcpy(ciph, out, ciphlen); err = gcry_cipher_decrypt (hdd, out, plainlen, ciph, ciphlen); } if (err) { fail ("cipher-xts, gcry_cipher_decrypt (tv %d) failed: %s\n", tidx, gpg_strerror (err)); goto err_out; } /* Check that the decrypt output matches the expected plain text. */ if (memcmp (plain, out, plainlen)) { mismatch (plain, plainlen, out, plainlen); fail ("cipher-xts, decrypt data mismatch (tv %d)\n", tidx); } if (0) { err_out: got_err = 1; } next_tv: gcry_cipher_close (hde); gcry_cipher_close (hdd); xfree (iv); xfree (ciph); xfree (plain); xfree (key); xfree (out); } if (verbose) fprintf (stderr, " Completed XTS checks.\n"); } static void check_xts_cipher (void) { /* Check XTS cipher with separate destination and source buffers for * encryption/decryption. */ do_check_xts_cipher(0); /* Check XTS cipher with inplace encrypt/decrypt. */ do_check_xts_cipher(1); } static void check_gost28147_cipher_basic (enum gcry_cipher_algos algo) { #if USE_GOST28147 static const struct { char key[MAX_DATA_LEN]; const char *oid; unsigned char plaintext[MAX_DATA_LEN]; int inlen; char out[MAX_DATA_LEN]; } tv[] = { { "\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x80" "\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xd0", "1.2.643.7.1.2.5.1.1", "\x01\x02\x03\x04\x05\x06\x07\x08", 8, "\xce\x5a\x5e\xd7\xe0\x57\x7a\x5f", }, { "\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x80" "\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xd0", "1.2.643.2.2.31.0", "\x01\x02\x03\x04\x05\x06\x07\x08", 8, "\x98\x56\xcf\x8b\xfc\xc2\x82\xf4", }, { "\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x80" "\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xd0", "1.2.643.2.2.31.1", "\x01\x02\x03\x04\x05\x06\x07\x08", 8, "\x66\x81\x84\xae\xdc\x48\xc9\x17", }, { "\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x80" "\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xd0", "1.2.643.2.2.31.2", "\x01\x02\x03\x04\x05\x06\x07\x08", 8, "\xdb\xee\x81\x14\x7b\x74\xb0\xf2", }, { "\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x80" "\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xd0", "1.2.643.2.2.31.3", "\x01\x02\x03\x04\x05\x06\x07\x08", 8, "\x31\xa3\x85\x9d\x0a\xee\xb8\x0e", }, { "\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x80" "\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xd0", "1.2.643.2.2.31.4", "\x01\x02\x03\x04\x05\x06\x07\x08", 8, "\xb1\x32\x3e\x0b\x21\x73\xcb\xd1", }, { "\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x80" "\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xd0", "1.2.643.2.2.30.0", "\x01\x02\x03\x04\x05\x06\x07\x08", 8, "\xce\xd5\x2a\x7f\xf7\xf2\x60\xd5", }, { "\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x80" "\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xd0", "1.2.643.2.2.30.1", "\x01\x02\x03\x04\x05\x06\x07\x08", 8, "\xe4\x21\x75\xe1\x69\x22\xd0\xa8", } }; gcry_cipher_hd_t hde, hdd; unsigned char out[MAX_DATA_LEN]; int i, keylen; gcry_error_t err = 0; if (verbose) fprintf (stderr, " Starting GOST28147 cipher checks.\n"); if (gcry_cipher_test_algo (algo) && in_fips_mode) { if (verbose) fprintf (stderr, " algorithm %d not available in fips mode\n", algo); return; } keylen = gcry_cipher_get_algo_keylen(algo); if (!keylen) { fail ("gost28147, gcry_cipher_get_algo_keylen failed\n"); return; } for (i = 0; i < sizeof (tv) / sizeof (tv[0]); i++) { err = gcry_cipher_open (&hde, algo, GCRY_CIPHER_MODE_ECB, 0); if (!err) err = gcry_cipher_open (&hdd, algo, GCRY_CIPHER_MODE_ECB, 0); if (err) { fail ("gost28147, gcry_cipher_open failed: %s\n", gpg_strerror (err)); return; } err = gcry_cipher_setkey (hde, tv[i].key, keylen); if (!err) err = gcry_cipher_setkey (hdd, tv[i].key, keylen); if (err) { fail ("gost28147, gcry_cipher_setkey failed: %s\n", gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } err = gcry_cipher_set_sbox (hde, tv[i].oid); if (!err) err = gcry_cipher_set_sbox (hdd, tv[i].oid); if (err) { fail ("gost28147, gcry_cipher_set_sbox failed: %s\n", gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } err = gcry_cipher_encrypt (hde, out, MAX_DATA_LEN, tv[i].plaintext, tv[i].inlen == -1 ? strlen ((char*)tv[i].plaintext) : tv[i].inlen); if (err) { fail ("gost28147, gcry_cipher_encrypt (%d) failed: %s\n", i, gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } if (memcmp (tv[i].out, out, tv[i].inlen)) { fail ("gost28147, encrypt mismatch entry %d\n", i); mismatch (tv[i].out, tv[i].inlen, out, tv[i].inlen); } err = gcry_cipher_decrypt (hdd, out, tv[i].inlen, NULL, 0); if (err) { fail ("gost28147, gcry_cipher_decrypt (%d) failed: %s\n", i, gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } if (memcmp (tv[i].plaintext, out, tv[i].inlen)) { fail ("gost28147, decrypt mismatch entry %d\n", i); mismatch (tv[i].plaintext, tv[i].inlen, out, tv[i].inlen); } gcry_cipher_close (hde); gcry_cipher_close (hdd); } #endif } static void check_gost28147_cipher (void) { check_gost28147_cipher_basic (GCRY_CIPHER_GOST28147); check_gost28147_cipher_basic (GCRY_CIPHER_GOST28147_MESH); } static void check_stream_cipher (void) { static const struct tv { const char *name; int algo; int keylen; int ivlen; const char *key; const char *iv; struct data { unsigned int inlen; const char *plaintext; const char *out; } data[MAX_DATA_LEN]; } tv[] = { #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 (in_fips_mode && mode == GCRY_CIPHER_MODE_GCM) { if (!err) fail ("pass %d, algo %d, mode %d, gcry_cipher_encrypt is expected to " "fail in FIPS mode: %s\n", pass, algo, mode, gpg_strerror (err)); goto err_out_free; } if (err) { fail ("pass %d, algo %d, mode %d, gcry_cipher_encrypt failed: %s\n", pass, algo, mode, gpg_strerror (err)); gcry_cipher_close (hd); goto err_out_free; } if (taglen > 0) { clutter_vector_registers(); err = gcry_cipher_gettag (hd, tag, taglen); if (err) { fail ("pass %d, algo %d, mode %d, gcry_cipher_gettag failed: %s\n", pass, algo, mode, gpg_strerror (err)); gcry_cipher_close (hd); goto err_out_free; } memcpy(tag_result, tag, taglen); } memcpy (enc_result, out, nplain); if (check_one_cipher_core_reset (hd, algo, mode, pass, nplain) < 0) goto err_out_free; clutter_vector_registers(); err = gcry_cipher_decrypt (hd, in, nplain, out, nplain); if (err) { fail ("pass %d, algo %d, mode %d, gcry_cipher_decrypt failed: %s\n", pass, algo, mode, gpg_strerror (err)); gcry_cipher_close (hd); goto err_out_free; } if (taglen > 0) { clutter_vector_registers(); err = gcry_cipher_checktag (hd, tag_result, taglen); if (err) { fail ("pass %d, algo %d, mode %d, gcry_cipher_checktag failed: %s\n", pass, algo, mode, gpg_strerror (err)); gcry_cipher_close (hd); goto err_out_free; } } if (memcmp (plain, in, nplain)) fail ("pass %d, algo %d, mode %d, encrypt-decrypt mismatch\n", pass, algo, mode); /* Again, using in-place encryption. */ if (check_one_cipher_core_reset (hd, algo, mode, pass, nplain) < 0) goto err_out_free; memcpy (out, plain, nplain); clutter_vector_registers(); err = gcry_cipher_encrypt (hd, out, nplain, NULL, 0); if (err) { fail ("pass %d, algo %d, mode %d, in-place, gcry_cipher_encrypt failed:" " %s\n", pass, algo, mode, gpg_strerror (err)); gcry_cipher_close (hd); goto err_out_free; } if (taglen > 0) { err = gcry_cipher_gettag (hd, tag, taglen); if (err) { fail ("pass %d, algo %d, mode %d, in-place, " "gcry_cipher_gettag failed: %s\n", pass, algo, mode, gpg_strerror (err)); gcry_cipher_close (hd); goto err_out_free; } if (memcmp (tag_result, tag, taglen)) fail ("pass %d, algo %d, mode %d, in-place, tag mismatch\n", pass, algo, mode); } if (memcmp (enc_result, out, nplain)) fail ("pass %d, algo %d, mode %d, in-place, encrypt mismatch\n", pass, algo, mode); if (check_one_cipher_core_reset (hd, algo, mode, pass, nplain) < 0) goto err_out_free; clutter_vector_registers(); err = gcry_cipher_decrypt (hd, out, nplain, NULL, 0); if (err) { fail ("pass %d, algo %d, mode %d, in-place, gcry_cipher_decrypt failed:" " %s\n", pass, algo, mode, gpg_strerror (err)); gcry_cipher_close (hd); goto err_out_free; } if (taglen > 0) { clutter_vector_registers(); err = gcry_cipher_checktag (hd, tag_result, taglen); if (err) { fail ("pass %d, algo %d, mode %d, in-place, " "gcry_cipher_checktag failed: %s\n", pass, algo, mode, gpg_strerror (err)); gcry_cipher_close (hd); goto err_out_free; } } if (memcmp (plain, out, nplain)) fail ("pass %d, algo %d, mode %d, in-place, encrypt-decrypt mismatch\n", pass, algo, mode); /* Again, splitting encryption in multiple operations. */ if (check_one_cipher_core_reset (hd, algo, mode, pass, nplain) < 0) goto err_out_free; piecelen = blklen; pos = 0; while (pos < nplain) { if (piecelen > nplain - pos) piecelen = nplain - pos; clutter_vector_registers(); err = gcry_cipher_encrypt (hd, out + pos, piecelen, plain + pos, piecelen); if (err) { fail ("pass %d, algo %d, mode %d, split-buffer (pos: %d, " "piecelen: %d), gcry_cipher_encrypt failed: %s\n", pass, algo, mode, pos, piecelen, gpg_strerror (err)); gcry_cipher_close (hd); goto err_out_free; } pos += piecelen; piecelen = 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 (); if (!in_fips_mode) { /* This will have to go through modifications as the GCM fails in fips * as late as in gcry_cipher_gettag, but we want to allow it in the end */ check_gcm_cipher (); } check_poly1305_cipher (); check_ocb_cipher (); check_xts_cipher (); check_eax_cipher (); check_siv_cipher (); check_gcm_siv_cipher (); check_gost28147_cipher (); check_stream_cipher (); check_stream_cipher_large_block (); if (verbose) fprintf (stderr, "Completed Cipher Mode checks.\n"); } static void fillbuf_count (char *buf, size_t buflen, unsigned char pos) { while (buflen--) *((unsigned char *)(buf++)) = pos++; } static void check_one_md (int algo, const char *data, int len, const char *expect, int elen, const char *key, int klen) { gcry_md_hd_t hd, hd2; unsigned char *p; int mdlen; int i, j; int xof = 0; gcry_error_t err = 0; err = gcry_md_open (&hd, algo, 0); if (err) { fail ("algo %d, gcry_md_open failed: %s\n", algo, gpg_strerror (err)); return; } mdlen = gcry_md_get_algo_dlen (algo); if (mdlen < 1 || mdlen > 500) { if (mdlen == 0 && (algo == GCRY_MD_SHAKE128 || algo == GCRY_MD_SHAKE256)) { xof = 1; } else { gcry_md_close (hd); fail ("algo %d, gcry_md_get_algo_dlen failed: %d\n", algo, mdlen); return; } } if (key && klen) { clutter_vector_registers(); err = gcry_md_setkey (hd, key, klen); if (err) { gcry_md_close (hd); fail ("algo %d, gcry_md_setkey failed: %s\n", algo, gpg_strerror (err)); return; } } if (*data == '!' && !data[1] && !xof) { unsigned char *p1, *p2; char buf[129]; /* Test hashing small input sizes first as full block, then byte-by-byte * and check that resulting digests are the same. */ err = gcry_md_open (&hd2, algo, 0); if (err) { gcry_md_close (hd); fail ("algo %d, gcry_md_open failed: %s\n", algo, gpg_strerror (err)); return; } if (key && klen) { clutter_vector_registers(); err = gcry_md_setkey (hd2, key, klen); if (err) { gcry_md_close (hd); gcry_md_close (hd2); fail ("algo %d, gcry_md_setkey failed: %s\n", algo, gpg_strerror (err)); return; } } for (i = 0; i < sizeof(buf); i++) buf[i] = i; for (i = 1; i < sizeof(buf); i++) { gcry_md_reset (hd); gcry_md_reset (hd2); clutter_vector_registers(); gcry_md_write (hd, buf, i); for (j = 0; j < i; j++) gcry_md_write (hd2, &buf[j], 1); clutter_vector_registers(); p1 = gcry_md_read (hd, algo); p2 = gcry_md_read (hd2, algo); if (memcmp (p1, p2, mdlen)) { printf ("full block (input length %d): ", i); for (i = 0; i < mdlen; i++) printf ("%02x ", p1[i] & 0xFF); printf ("\nbyte-by-byte: "); for (i = 0; i < mdlen; i++) printf ("%02x ", p2[i] & 0xFF); printf ("\n"); fail ("algo %d, digest mismatch\n", algo); } } gcry_md_close (hd2); gcry_md_reset (hd); } if ((*data == '!' && !data[1]) || /* hash one million times a "a" */ (*data == '?' && !data[1])) /* hash million byte data-set with byte pattern 0x00,0x01,0x02,... */ { char aaa[1000]; size_t left = 1000 * 1000; size_t startlen = 1; size_t piecelen = startlen; if (*data == '!') memset (aaa, 'a', 1000); /* Write in chuck with all sizes 1 to 1000 (500500 bytes) */ for (i = 1; i <= 1000 && left > 0; i++) { piecelen = i; if (piecelen > sizeof(aaa)) piecelen = sizeof(aaa); if (piecelen > left) piecelen = left; if (*data == '?') fillbuf_count(aaa, piecelen, 1000 * 1000 - left); clutter_vector_registers(); gcry_md_write (hd, aaa, piecelen); left -= piecelen; } /* Write in odd size chunks so that we test the buffering. */ while (left > 0) { if (piecelen > sizeof(aaa)) piecelen = sizeof(aaa); if (piecelen > left) piecelen = left; if (*data == '?') fillbuf_count(aaa, piecelen, 1000 * 1000 - left); clutter_vector_registers(); gcry_md_write (hd, aaa, piecelen); left -= piecelen; if (piecelen == sizeof(aaa)) piecelen = ++startlen; else piecelen = piecelen * 2 - ((piecelen != startlen) ? startlen : 0); } } else { clutter_vector_registers(); gcry_md_write (hd, data, len); } clutter_vector_registers(); err = gcry_md_copy (&hd2, hd); if (err) { fail ("algo %d, gcry_md_copy failed: %s\n", algo, gpg_strerror (err)); } gcry_md_close (hd); if (!xof) { static const char buf[128]; clutter_vector_registers(); p = gcry_md_read (hd2, algo); if (memcmp (p, expect, mdlen)) { printf ("computed: "); for (i = 0; i < mdlen; i++) printf ("%02x ", p[i] & 0xFF); printf ("\nexpected: "); for (i = 0; i < mdlen; i++) printf ("%02x ", expect[i] & 0xFF); printf ("\n"); fail ("algo %d, digest mismatch\n", algo); } /* Write after final/read is allowed for timing attack mitigation * purposes. Try writing and see if we catch fire. */ clutter_vector_registers(); gcry_md_write (hd2, buf, sizeof(buf)); } else { char buf[1000]; int outmax = sizeof(buf) > elen ? elen : sizeof(buf); clutter_vector_registers(); err = gcry_md_copy (&hd, hd2); if (err) { fail ("algo %d, gcry_md_copy failed: %s\n", algo, gpg_strerror (err)); } clutter_vector_registers(); err = gcry_md_extract(hd2, algo, buf, outmax); if (err) { fail ("algo %d, gcry_md_extract failed: %s\n", algo, gpg_strerror (err)); } if (memcmp (buf, expect, outmax)) { printf ("computed: "); for (i = 0; i < outmax; i++) printf ("%02x ", buf[i] & 0xFF); printf ("\nexpected: "); for (i = 0; i < outmax; i++) printf ("%02x ", expect[i] & 0xFF); printf ("\n"); fail ("algo %d, digest mismatch\n", algo); } memset(buf, 0, sizeof(buf)); /* Extract one byte at time. */ clutter_vector_registers(); for (i = 0; i < outmax && !err; i++) err = gcry_md_extract(hd, algo, &buf[i], 1); if (err) { fail ("algo %d, gcry_md_extract failed: %s\n", algo, gpg_strerror (err)); } if (memcmp (buf, expect, outmax)) { printf ("computed: "); for (i = 0; i < outmax; i++) printf ("%02x ", buf[i] & 0xFF); printf ("\nexpected: "); for (i = 0; i < outmax; i++) printf ("%02x ", expect[i] & 0xFF); printf ("\n"); fail ("algo %d, digest mismatch\n", algo); } if (*data == '!' && !data[1]) { int crcalgo = GCRY_MD_SHA256; gcry_md_hd_t crc1, crc2; size_t startlen; size_t piecelen; size_t left; const unsigned char *p1, *p2; int crclen; crclen = gcry_md_get_algo_dlen (crcalgo); err = gcry_md_open (&crc1, crcalgo, 0); if (err) { fail ("algo %d, crcalgo: %d, gcry_md_open failed: %s\n", algo, crcalgo, gpg_strerror (err)); return; } err = gcry_md_open (&crc2, crcalgo, 0); if (err) { fail ("algo %d, crcalgo: %d, gcry_md_open failed: %s\n", algo, crcalgo, gpg_strerror (err)); return; } /* Extract large chucks, total 1000000 additional bytes. */ for (i = 0; i < 1000; i++) { clutter_vector_registers(); err = gcry_md_extract(hd, algo, buf, 1000); if (!err) gcry_md_write(crc1, buf, 1000); } if (err) { fail ("algo %d, gcry_md_extract failed: %s\n", algo, gpg_strerror (err)); } /* Extract in odd size chunks, total 1000000 additional bytes. */ left = 1000 * 1000; startlen = 1; piecelen = startlen; while (!err && left > 0) { if (piecelen > sizeof(buf)) piecelen = sizeof(buf); if (piecelen > left) piecelen = left; clutter_vector_registers(); err = gcry_md_extract (hd2, algo, buf, piecelen); if (!err) gcry_md_write(crc2, buf, piecelen); if (err) { fail ("algo %d, gcry_md_extract failed: %s\n", algo, gpg_strerror (err)); } left -= piecelen; if (piecelen == sizeof(buf)) piecelen = ++startlen; else piecelen = piecelen * 2 - ((piecelen != startlen) ? startlen : 0); } clutter_vector_registers(); p1 = gcry_md_read (crc1, crcalgo); clutter_vector_registers(); p2 = gcry_md_read (crc2, crcalgo); if (memcmp (p1, p2, crclen)) { printf ("computed: "); for (i = 0; i < crclen; i++) printf ("%02x ", p2[i] & 0xFF); printf ("\nexpected: "); for (i = 0; i < crclen; i++) printf ("%02x ", p1[i] & 0xFF); printf ("\n"); fail ("algo %d, large xof output mismatch\n", algo); } gcry_md_close (crc1); gcry_md_close (crc2); } gcry_md_close (hd); } gcry_md_close (hd2); } static void check_one_md_multi (int algo, const char *data, int len, const char *expect) { gpg_error_t err; gcry_buffer_t iov[3]; int iovcnt; char digest[64]; int mdlen; int i; mdlen = gcry_md_get_algo_dlen (algo); if (mdlen < 1 || mdlen > 64) { if (mdlen == 0 && (algo == GCRY_MD_SHAKE128 || algo == GCRY_MD_SHAKE256)) return; fail ("check_one_md_multi: algo %d, gcry_md_get_algo_dlen failed: %d\n", algo, mdlen); return; } if (*data == '!' && !data[1]) return; /* We can't do that here. */ if (*data == '?' && !data[1]) return; /* We can't do that here. */ memset (iov, 0, sizeof iov); iov[0].data = (void*)data; if (len) { iov[0].len = 1; len--; data++; } iovcnt = 1; if (len >= 4) { iov[iovcnt].data = (void*)data; iov[iovcnt].len = 4; iovcnt++; data += 4; len -= 4; } iov[iovcnt].data = (void*)data; iov[iovcnt].len = len; iovcnt++; assert (iovcnt <= DIM (iov)); clutter_vector_registers(); err = gcry_md_hash_buffers (algo, 0, digest, iov, iovcnt); if (err) { fail ("check_one_md_multi: algo %d, gcry_hash_buffers failed: %s\n", algo, gpg_strerror (err)); return; } if (memcmp (digest, expect, mdlen)) { printf ("computed: "); for (i = 0; i < mdlen; i++) printf ("%02x ", digest[i] & 0xFF); printf ("\nexpected: "); for (i = 0; i < mdlen; i++) printf ("%02x ", expect[i] & 0xFF); printf ("\n"); fail ("check_one_md_multi: algo %d, digest mismatch\n", algo); } } static void check_one_md_final(int algo, const char *expect, unsigned int expectlen) { const unsigned int max_inbuf_len = 288 + 1; char *inbuf; char xorbuf[64]; char digest[64]; unsigned int mdlen; int i, j; mdlen = gcry_md_get_algo_dlen (algo); if (mdlen < 1 || mdlen > 64) { return; } if (expectlen == 0) expectlen = mdlen; if (expectlen != mdlen) { fail ("check_one_md_final: algo %d, digest length mismatch\n", algo); return; } clutter_vector_registers(); gcry_md_hash_buffer (algo, xorbuf, NULL, 0); for (i = 1; i < max_inbuf_len; i++) { inbuf = xmalloc(i); if (!inbuf) { fail ("out-of-memory\n"); return; } for (j = 0; j < i; j++) inbuf[j] = j; gcry_md_hash_buffer (algo, digest, inbuf, i); for (j = 0; j < expectlen; j++) xorbuf[j] ^= digest[j]; xfree (inbuf); } if (memcmp(expect, xorbuf, expectlen) != 0) { printf ("computed: "); for (i = 0; i < expectlen; i++) printf ("%02x ", xorbuf[i] & 0xFF); printf ("\nexpected: "); for (i = 0; i < expectlen; i++) printf ("%02x ", expect[i] & 0xFF); printf ("\n"); fail ("check_one_md_final: algo %d, digest mismatch\n", algo); } } static void check_digests (void) { static const char blake2_data_vector[] = "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f" "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f" "\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f" "\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f" "\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f" "\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f" "\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f" "\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f" "\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f" "\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f" "\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf" "\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf" "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf" "\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf" "\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef" "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff"; static const struct algos { int md; const char *data; const char *expect; int datalen; int expectlen; const char *key; int keylen; } algos[] = { { GCRY_MD_MD2, "", "\x83\x50\xe5\xa3\xe2\x4c\x15\x3d\xf2\x27\x5c\x9f\x80\x69\x27\x73" }, { GCRY_MD_MD2, "a", "\x32\xec\x01\xec\x4a\x6d\xac\x72\xc0\xab\x96\xfb\x34\xc0\xb5\xd1" }, { GCRY_MD_MD2, "message digest", "\xab\x4f\x49\x6b\xfb\x2a\x53\x0b\x21\x9f\xf3\x30\x31\xfe\x06\xb0" }, { GCRY_MD_MD4, "", "\x31\xD6\xCF\xE0\xD1\x6A\xE9\x31\xB7\x3C\x59\xD7\xE0\xC0\x89\xC0" }, { GCRY_MD_MD4, "a", "\xbd\xe5\x2c\xb3\x1d\xe3\x3e\x46\x24\x5e\x05\xfb\xdb\xd6\xfb\x24" }, { GCRY_MD_MD4, "message digest", "\xd9\x13\x0a\x81\x64\x54\x9f\xe8\x18\x87\x48\x06\xe1\xc7\x01\x4b" }, { GCRY_MD_MD5, "", "\xD4\x1D\x8C\xD9\x8F\x00\xB2\x04\xE9\x80\x09\x98\xEC\xF8\x42\x7E" }, { GCRY_MD_MD5, "a", "\x0C\xC1\x75\xB9\xC0\xF1\xB6\xA8\x31\xC3\x99\xE2\x69\x77\x26\x61" }, { GCRY_MD_MD5, "abc", "\x90\x01\x50\x98\x3C\xD2\x4F\xB0\xD6\x96\x3F\x7D\x28\xE1\x7F\x72" }, { GCRY_MD_MD5, "message digest", "\xF9\x6B\x69\x7D\x7C\xB7\x93\x8D\x52\x5A\x2F\x31\xAA\xF1\x61\xD0" }, { GCRY_MD_MD5, "Libgcrypt is free software; you can redistribute it and/or modif" "y it under the terms of the GNU Lesser general Public License as" " published by the Free Software Foundation; either version 2.1 o" "f the License, or (at your option) any later version.\nLibgcrypt" " is distributed in the hope that it will be useful, but WITHOUT " "ANY WARRANTY; without even the implied warranty of MERCHANTABILI" "TY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser Gene" "ral Public License for more details.", "\xc4\x1a\x5c\x0b\x44\x5f\xba\x1a\xda\xbc\xc0\x38\x0e\x0c\x9e\x33" }, { GCRY_MD_MD5, "!", "\x77\x07\xd6\xae\x4e\x02\x7c\x70\xee\xa2\xa9\x35\xc2\x29\x6f\x21" }, { GCRY_MD_MD5, "?", "\x5c\x72\x5c\xbc\x2d\xbb\xe1\x14\x81\x59\xe9\xd9\xcf\x90\x64\x8f" }, { GCRY_MD_SHA1, "abc", "\xA9\x99\x3E\x36\x47\x06\x81\x6A\xBA\x3E" "\x25\x71\x78\x50\xC2\x6C\x9C\xD0\xD8\x9D" }, { GCRY_MD_SHA1, "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", "\x84\x98\x3E\x44\x1C\x3B\xD2\x6E\xBA\xAE" "\x4A\xA1\xF9\x51\x29\xE5\xE5\x46\x70\xF1" }, { GCRY_MD_SHA1, "!" /* kludge for "a"*1000000 */ , "\x34\xAA\x97\x3C\xD4\xC4\xDA\xA4\xF6\x1E" "\xEB\x2B\xDB\xAD\x27\x31\x65\x34\x01\x6F" }, { GCRY_MD_SHA1, "?" /* kludge for "\x00\x01\x02"..."\xfe\xff\x00\x01"... (length 1000000) */ , "\x5f\x8d\x3c\x4f\x12\xf0\x49\x9e\x28\x73" "\x79\xec\x97\x3b\x98\x4c\x94\x75\xaa\x8f" }, { GCRY_MD_SHA1, "Libgcrypt is free software; you can redistribute it and/or modif" "y it under the terms of the GNU Lesser general Public License as" " published by the Free Software Foundation; either version 2.1 o" "f the License, or (at your option) any later version.\nLibgcrypt" " is distributed in the hope that it will be useful, but WITHOUT " "ANY WARRANTY; without even the implied warranty of MERCHANTABILI" "TY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser Gene" "ral Public License for more details.", "\xf5\xd9\xcb\x66\x91\xb4\x7a\x7c\x60\x35\xe2\x1c\x38\x26\x52\x13" "\x8e\xd5\xe5\xdf" }, /* From RFC3874 */ { GCRY_MD_SHA224, "abc", "\x23\x09\x7d\x22\x34\x05\xd8\x22\x86\x42\xa4\x77\xbd\xa2\x55\xb3" "\x2a\xad\xbc\xe4\xbd\xa0\xb3\xf7\xe3\x6c\x9d\xa7" }, { GCRY_MD_SHA224, "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", "\x75\x38\x8b\x16\x51\x27\x76\xcc\x5d\xba\x5d\xa1\xfd\x89\x01\x50" "\xb0\xc6\x45\x5c\xb4\xf5\x8b\x19\x52\x52\x25\x25" }, { GCRY_MD_SHA224, "!", "\x20\x79\x46\x55\x98\x0c\x91\xd8\xbb\xb4\xc1\xea\x97\x61\x8a\x4b" "\xf0\x3f\x42\x58\x19\x48\xb2\xee\x4e\xe7\xad\x67" }, { GCRY_MD_SHA224, "?", "\xfa\xb9\xf0\xdf\x12\xfe\xa1\x1a\x34\x78\x96\x31\xe6\x53\x48\xbf" "\x3b\xca\x70\x78\xf2\x44\xdf\x62\xab\x27\xb8\xda" }, { GCRY_MD_SHA224, "Libgcrypt is free software; you can redistribute it and/or modif" "y it under the terms of the GNU Lesser general Public License as" " published by the Free Software Foundation; either version 2.1 o" "f the License, or (at your option) any later version.\nLibgcrypt" " is distributed in the hope that it will be useful, but WITHOUT " "ANY WARRANTY; without even the implied warranty of MERCHANTABILI" "TY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser Gene" "ral Public License for more details.", "\x80\xf0\x60\x79\xb0\xe9\x65\xab\x8a\x76\xbf\x6e\x88\x64\x75\xe7" "\xfd\xf0\xc2\x4c\xf6\xf2\xa6\x01\xed\x50\x71\x08" }, { GCRY_MD_SHA256, "abc", "\xba\x78\x16\xbf\x8f\x01\xcf\xea\x41\x41\x40\xde\x5d\xae\x22\x23" "\xb0\x03\x61\xa3\x96\x17\x7a\x9c\xb4\x10\xff\x61\xf2\x00\x15\xad" }, { GCRY_MD_SHA256, "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", "\x24\x8d\x6a\x61\xd2\x06\x38\xb8\xe5\xc0\x26\x93\x0c\x3e\x60\x39" "\xa3\x3c\xe4\x59\x64\xff\x21\x67\xf6\xec\xed\xd4\x19\xdb\x06\xc1" }, { GCRY_MD_SHA256, "!", "\xcd\xc7\x6e\x5c\x99\x14\xfb\x92\x81\xa1\xc7\xe2\x84\xd7\x3e\x67" "\xf1\x80\x9a\x48\xa4\x97\x20\x0e\x04\x6d\x39\xcc\xc7\x11\x2c\xd0" }, { GCRY_MD_SHA256, "?", "\x67\x87\x0d\xfc\x9c\x64\xe7\xaa\x27\x0a\x3f\x7e\x80\x51\xae\x65" "\xd2\x07\xf9\x3f\xc3\xdf\x04\xd7\x57\x2e\x63\x65\xaf\x69\xcd\x0d" }, { GCRY_MD_SHA256, "Libgcrypt is free software; you can redistribute it and/or modif" "y it under the terms of the GNU Lesser general Public License as" " published by the Free Software Foundation; either version 2.1 o" "f the License, or (at your option) any later version.\nLibgcrypt" " is distributed in the hope that it will be useful, but WITHOUT " "ANY WARRANTY; without even the implied warranty of MERCHANTABILI" "TY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser Gene" "ral Public License for more details.", "\xb0\x18\x70\x67\xb8\xac\x68\x50\xec\x95\x43\x77\xb5\x44\x5b\x0f" "\x2e\xbd\x40\xc9\xdc\x2a\x2c\x33\x8b\x53\xeb\x3e\x9e\x01\xd7\x02" }, { GCRY_MD_SHA384, "abc", "\xcb\x00\x75\x3f\x45\xa3\x5e\x8b\xb5\xa0\x3d\x69\x9a\xc6\x50\x07" "\x27\x2c\x32\xab\x0e\xde\xd1\x63\x1a\x8b\x60\x5a\x43\xff\x5b\xed" "\x80\x86\x07\x2b\xa1\xe7\xcc\x23\x58\xba\xec\xa1\x34\xc8\x25\xa7" }, { GCRY_MD_SHA384, "Libgcrypt is free software; you can redistribute it and/or modif" "y it under the terms of the GNU Lesser general Public License as" " published by the Free Software Foundation; either version 2.1 o" "f the License, or (at your option) any later version.\nLibgcrypt" " is distributed in the hope that it will be useful, but WITHOUT " "ANY WARRANTY; without even the implied warranty of MERCHANTABILI" "TY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser Gene" "ral Public License for more details.", "\xe4\x6d\xb4\x28\x33\x77\x99\x49\x94\x0f\xcf\x87\xc2\x2f\x30\xd6" "\x06\x24\x82\x9d\x80\x64\x8a\x07\xa1\x20\x8f\x5f\xf3\x85\xb3\xaa" "\x39\xb8\x61\x00\xfc\x7f\x18\xc6\x82\x23\x4b\x45\xfa\xf1\xbc\x69" }, { GCRY_MD_SHA384, "!", "\x9d\x0e\x18\x09\x71\x64\x74\xcb\x08\x6e\x83\x4e\x31\x0a\x4a\x1c" "\xed\x14\x9e\x9c\x00\xf2\x48\x52\x79\x72\xce\xc5\x70\x4c\x2a\x5b" "\x07\xb8\xb3\xdc\x38\xec\xc4\xeb\xae\x97\xdd\xd8\x7f\x3d\x89\x85" }, { GCRY_MD_SHA384, "?", "\xfa\x77\xbb\x86\x3a\xd5\xae\x88\xa9\x9c\x5e\xda\xb5\xc7\xcb\x40" "\xcd\xf4\x30\xef\xa8\x1b\x23\x7b\xa9\xde\xfd\x81\x12\xf6\x7e\xed" "\xa7\xd2\x27\x91\xd1\xbc\x76\x44\x57\x59\x71\x11\xe6\x8a\x2c\xde" }, { GCRY_MD_SHA512, "abc", "\xDD\xAF\x35\xA1\x93\x61\x7A\xBA\xCC\x41\x73\x49\xAE\x20\x41\x31" "\x12\xE6\xFA\x4E\x89\xA9\x7E\xA2\x0A\x9E\xEE\xE6\x4B\x55\xD3\x9A" "\x21\x92\x99\x2A\x27\x4F\xC1\xA8\x36\xBA\x3C\x23\xA3\xFE\xEB\xBD" "\x45\x4D\x44\x23\x64\x3C\xE8\x0E\x2A\x9A\xC9\x4F\xA5\x4C\xA4\x9F" }, { GCRY_MD_SHA512, "Libgcrypt is free software; you can redistribute it and/or modif" "y it under the terms of the GNU Lesser general Public License as" " published by the Free Software Foundation; either version 2.1 o" "f the License, or (at your option) any later version.\nLibgcrypt" " is distributed in the hope that it will be useful, but WITHOUT " "ANY WARRANTY; without even the implied warranty of MERCHANTABILI" "TY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser Gene" "ral Public License for more details.", "\x72\x8c\xde\xd8\xe4\xd7\xb6\xa5\x0f\xde\x6b\x4d\x33\xaf\x15\x19" "\xdd\xec\x62\x0f\xf7\x1a\x1e\x10\x32\x05\x02\xa6\xb0\x1f\x70\x37" "\xbc\xd7\x15\xed\x71\x6c\x78\x20\xc8\x54\x87\xd0\x66\x6a\x17\x83" "\x05\x61\x92\xbe\xcc\x8f\x3b\xbf\x11\x72\x22\x69\x23\x5b\x48\x5c" }, { GCRY_MD_SHA512, "!", "\xe7\x18\x48\x3d\x0c\xe7\x69\x64\x4e\x2e\x42\xc7\xbc\x15\xb4\x63" "\x8e\x1f\x98\xb1\x3b\x20\x44\x28\x56\x32\xa8\x03\xaf\xa9\x73\xeb" "\xde\x0f\xf2\x44\x87\x7e\xa6\x0a\x4c\xb0\x43\x2c\xe5\x77\xc3\x1b" "\xeb\x00\x9c\x5c\x2c\x49\xaa\x2e\x4e\xad\xb2\x17\xad\x8c\xc0\x9b" }, { GCRY_MD_SHA512, "?", "\x91\xe9\x42\x4e\xa9\xdc\x44\x01\x40\x64\xa4\x5a\x69\xcc\xac\xa3" "\x74\xee\x78\xeb\x79\x1f\x94\x38\x5b\x73\xef\xf8\xfd\x5d\x74\xd8" "\x51\x36\xfe\x63\x52\xde\x07\x70\x95\xd6\x78\x2b\x7b\x46\x8a\x2c" "\x30\x0f\x48\x0c\x74\x43\x06\xdb\xa3\x8d\x64\x3d\xe9\xa1\xa7\x72" }, { GCRY_MD_SHA512_256, "abc", "\x53\x04\x8E\x26\x81\x94\x1E\xF9\x9B\x2E\x29\xB7\x6B\x4C\x7D\xAB" "\xE4\xC2\xD0\xC6\x34\xFC\x6D\x46\xE0\xE2\xF1\x31\x07\xE7\xAF\x23" }, { GCRY_MD_SHA512_256, "!", "\x9a\x59\xa0\x52\x93\x01\x87\xa9\x70\x38\xca\xe6\x92\xf3\x07\x08" "\xaa\x64\x91\x92\x3e\xf5\x19\x43\x94\xdc\x68\xd5\x6c\x74\xfb\x21" }, { GCRY_MD_SHA512_224, "abc", "\x46\x34\x27\x0F\x70\x7B\x6A\x54\xDA\xAE\x75\x30\x46\x08\x42\xE2" "\x0E\x37\xED\x26\x5C\xEE\xE9\xA4\x3E\x89\x24\xAA" }, { GCRY_MD_SHA512_224, "!", "\x37\xab\x33\x1d\x76\xf0\xd3\x6d\xe4\x22\xbd\x0e\xde\xb2\x2a\x28" "\xac\xcd\x48\x7b\x7a\x84\x53\xae\x96\x5d\xd2\x87" }, { GCRY_MD_SHA3_224, "abc", "\xe6\x42\x82\x4c\x3f\x8c\xf2\x4a\xd0\x92\x34\xee\x7d\x3c\x76\x6f" "\xc9\xa3\xa5\x16\x8d\x0c\x94\xad\x73\xb4\x6f\xdf" }, { GCRY_MD_SHA3_256, "abc", "\x3a\x98\x5d\xa7\x4f\xe2\x25\xb2\x04\x5c\x17\x2d\x6b\xd3\x90\xbd" "\x85\x5f\x08\x6e\x3e\x9d\x52\x5b\x46\xbf\xe2\x45\x11\x43\x15\x32" }, { GCRY_MD_SHA3_384, "abc", "\xec\x01\x49\x82\x88\x51\x6f\xc9\x26\x45\x9f\x58\xe2\xc6\xad\x8d" "\xf9\xb4\x73\xcb\x0f\xc0\x8c\x25\x96\xda\x7c\xf0\xe4\x9b\xe4\xb2" "\x98\xd8\x8c\xea\x92\x7a\xc7\xf5\x39\xf1\xed\xf2\x28\x37\x6d\x25" }, { GCRY_MD_SHA3_512, "abc", "\xb7\x51\x85\x0b\x1a\x57\x16\x8a\x56\x93\xcd\x92\x4b\x6b\x09\x6e" "\x08\xf6\x21\x82\x74\x44\xf7\x0d\x88\x4f\x5d\x02\x40\xd2\x71\x2e" "\x10\xe1\x16\xe9\x19\x2a\xf3\xc9\x1a\x7e\xc5\x76\x47\xe3\x93\x40" "\x57\x34\x0b\x4c\xf4\x08\xd5\xa5\x65\x92\xf8\x27\x4e\xec\x53\xf0" }, { GCRY_MD_SHA3_224, "", "\x6b\x4e\x03\x42\x36\x67\xdb\xb7\x3b\x6e\x15\x45\x4f\x0e\xb1\xab" "\xd4\x59\x7f\x9a\x1b\x07\x8e\x3f\x5b\x5a\x6b\xc7" }, { GCRY_MD_SHA3_256, "", "\xa7\xff\xc6\xf8\xbf\x1e\xd7\x66\x51\xc1\x47\x56\xa0\x61\xd6\x62" "\xf5\x80\xff\x4d\xe4\x3b\x49\xfa\x82\xd8\x0a\x4b\x80\xf8\x43\x4a" }, { GCRY_MD_SHA3_384, "", "\x0c\x63\xa7\x5b\x84\x5e\x4f\x7d\x01\x10\x7d\x85\x2e\x4c\x24\x85" "\xc5\x1a\x50\xaa\xaa\x94\xfc\x61\x99\x5e\x71\xbb\xee\x98\x3a\x2a" "\xc3\x71\x38\x31\x26\x4a\xdb\x47\xfb\x6b\xd1\xe0\x58\xd5\xf0\x04" }, { GCRY_MD_SHA3_512, "", "\xa6\x9f\x73\xcc\xa2\x3a\x9a\xc5\xc8\xb5\x67\xdc\x18\x5a\x75\x6e" "\x97\xc9\x82\x16\x4f\xe2\x58\x59\xe0\xd1\xdc\xc1\x47\x5c\x80\xa6" "\x15\xb2\x12\x3a\xf1\xf5\xf9\x4c\x11\xe3\xe9\x40\x2c\x3a\xc5\x58" "\xf5\x00\x19\x9d\x95\xb6\xd3\xe3\x01\x75\x85\x86\x28\x1d\xcd\x26" }, { GCRY_MD_SHA3_224, "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlm" "nomnopnopq", "\x8a\x24\x10\x8b\x15\x4a\xda\x21\xc9\xfd\x55\x74\x49\x44\x79\xba" "\x5c\x7e\x7a\xb7\x6e\xf2\x64\xea\xd0\xfc\xce\x33" }, { GCRY_MD_SHA3_256, "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlm" "nomnopnopq", "\x41\xc0\xdb\xa2\xa9\xd6\x24\x08\x49\x10\x03\x76\xa8\x23\x5e\x2c" "\x82\xe1\xb9\x99\x8a\x99\x9e\x21\xdb\x32\xdd\x97\x49\x6d\x33\x76" }, { GCRY_MD_SHA3_384, "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlm" "nomnopnopq", "\x99\x1c\x66\x57\x55\xeb\x3a\x4b\x6b\xbd\xfb\x75\xc7\x8a\x49\x2e" "\x8c\x56\xa2\x2c\x5c\x4d\x7e\x42\x9b\xfd\xbc\x32\xb9\xd4\xad\x5a" "\xa0\x4a\x1f\x07\x6e\x62\xfe\xa1\x9e\xef\x51\xac\xd0\x65\x7c\x22" }, { GCRY_MD_SHA3_512, "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlm" "nomnopnopq", "\x04\xa3\x71\xe8\x4e\xcf\xb5\xb8\xb7\x7c\xb4\x86\x10\xfc\xa8\x18" "\x2d\xd4\x57\xce\x6f\x32\x6a\x0f\xd3\xd7\xec\x2f\x1e\x91\x63\x6d" "\xee\x69\x1f\xbe\x0c\x98\x53\x02\xba\x1b\x0d\x8d\xc7\x8c\x08\x63" "\x46\xb5\x33\xb4\x9c\x03\x0d\x99\xa2\x7d\xaf\x11\x39\xd6\xe7\x5e" }, { GCRY_MD_SHA3_224, "abcdefghbcdefghicdefghijdefghijkefghijklfghijk" "lmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu", "\x54\x3e\x68\x68\xe1\x66\x6c\x1a\x64\x36\x30\xdf\x77\x36\x7a\xe5" "\xa6\x2a\x85\x07\x0a\x51\xc1\x4c\xbf\x66\x5c\xbc" }, { GCRY_MD_SHA3_256, "abcdefghbcdefghicdefghijdefghijkefghijklfghijk" "lmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu", "\x91\x6f\x60\x61\xfe\x87\x97\x41\xca\x64\x69\xb4\x39\x71\xdf\xdb" "\x28\xb1\xa3\x2d\xc3\x6c\xb3\x25\x4e\x81\x2b\xe2\x7a\xad\x1d\x18" }, { GCRY_MD_SHA3_384, "abcdefghbcdefghicdefghijdefghijkefghijklfghijk" "lmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu", "\x79\x40\x7d\x3b\x59\x16\xb5\x9c\x3e\x30\xb0\x98\x22\x97\x47\x91" "\xc3\x13\xfb\x9e\xcc\x84\x9e\x40\x6f\x23\x59\x2d\x04\xf6\x25\xdc" "\x8c\x70\x9b\x98\xb4\x3b\x38\x52\xb3\x37\x21\x61\x79\xaa\x7f\xc7" }, { GCRY_MD_SHA3_512, "abcdefghbcdefghicdefghijdefghijkefghijklfghijk" "lmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu", "\xaf\xeb\xb2\xef\x54\x2e\x65\x79\xc5\x0c\xad\x06\xd2\xe5\x78\xf9" "\xf8\xdd\x68\x81\xd7\xdc\x82\x4d\x26\x36\x0f\xee\xbf\x18\xa4\xfa" "\x73\xe3\x26\x11\x22\x94\x8e\xfc\xfd\x49\x2e\x74\xe8\x2e\x21\x89" "\xed\x0f\xb4\x40\xd1\x87\xf3\x82\x27\x0c\xb4\x55\xf2\x1d\xd1\x85" }, { GCRY_MD_SHA3_224, "!", "\xd6\x93\x35\xb9\x33\x25\x19\x2e\x51\x6a\x91\x2e\x6d\x19\xa1\x5c" "\xb5\x1c\x6e\xd5\xc1\x52\x43\xe7\xa7\xfd\x65\x3c" }, { GCRY_MD_SHA3_256, "!", "\x5c\x88\x75\xae\x47\x4a\x36\x34\xba\x4f\xd5\x5e\xc8\x5b\xff\xd6" "\x61\xf3\x2a\xca\x75\xc6\xd6\x99\xd0\xcd\xcb\x6c\x11\x58\x91\xc1" }, { GCRY_MD_SHA3_384, "!", "\xee\xe9\xe2\x4d\x78\xc1\x85\x53\x37\x98\x34\x51\xdf\x97\xc8\xad" "\x9e\xed\xf2\x56\xc6\x33\x4f\x8e\x94\x8d\x25\x2d\x5e\x0e\x76\x84" "\x7a\xa0\x77\x4d\xdb\x90\xa8\x42\x19\x0d\x2c\x55\x8b\x4b\x83\x40" }, { GCRY_MD_SHA3_512, "!", "\x3c\x3a\x87\x6d\xa1\x40\x34\xab\x60\x62\x7c\x07\x7b\xb9\x8f\x7e" "\x12\x0a\x2a\x53\x70\x21\x2d\xff\xb3\x38\x5a\x18\xd4\xf3\x88\x59" "\xed\x31\x1d\x0a\x9d\x51\x41\xce\x9c\xc5\xc6\x6e\xe6\x89\xb2\x66" "\xa8\xaa\x18\xac\xe8\x28\x2a\x0e\x0d\xb5\x96\xc9\x0b\x0a\x7b\x87" }, { GCRY_MD_SHA3_224, "?", "\x1b\xd1\xc6\x12\x02\x35\x52\x8b\x44\x7e\x16\x39\x20\x05\xec\x67" "\x2d\x57\x20\xe0\x90\xc9\x78\x08\x86\x4f\x1b\xd0" }, { GCRY_MD_SHA3_256, "?", "\xfe\xb7\xf4\x76\x78\x97\x48\x2f\xe2\x29\x1b\x66\x85\xc1\x7b\x45" "\xc5\x08\xed\x82\x50\xcc\x5d\x99\x96\xd2\xc3\x82\x1a\xa8\xd4\xa7" }, { GCRY_MD_SHA3_384, "?", "\x45\x1f\x0b\x93\x4b\xca\x3e\x65\x93\xd4\xaa\x8c\x18\xc1\x04\x84" "\x12\xd5\x1e\x35\xe1\x05\xd9\x77\x3f\xc1\x08\x8b\x77\x36\xad\x4a" "\x33\x70\xaf\x49\x8b\xea\x4c\x5c\x52\xe7\x5b\xed\x31\x74\x57\x12" }, { GCRY_MD_SHA3_512, "?", "\xa2\xee\xb5\x6f\x2a\x87\xa5\xb3\x9b\xd9\x1c\xf0\xaa\xdf\xb1\xd5" "\xad\x0a\x1a\xaa\xd3\x63\x81\xcf\xb8\x7c\x36\xa7\x80\x3b\x03\xd6" "\x31\x5c\x5d\x33\x8e\x52\xb1\x42\x4d\x27\x1c\xa2\xa5\xf2\xc5\x97" "\x10\x12\xe5\xee\x86\xa3\xcc\xaf\x91\x7a\x94\x28\x65\xea\x66\xe3" }, { GCRY_MD_RMD160, "", "\x9c\x11\x85\xa5\xc5\xe9\xfc\x54\x61\x28" "\x08\x97\x7e\xe8\xf5\x48\xb2\x25\x8d\x31" }, { GCRY_MD_RMD160, "a", "\x0b\xdc\x9d\x2d\x25\x6b\x3e\xe9\xda\xae" "\x34\x7b\xe6\xf4\xdc\x83\x5a\x46\x7f\xfe" }, { GCRY_MD_RMD160, "abc", "\x8e\xb2\x08\xf7\xe0\x5d\x98\x7a\x9b\x04" "\x4a\x8e\x98\xc6\xb0\x87\xf1\x5a\x0b\xfc" }, { GCRY_MD_RMD160, "message digest", "\x5d\x06\x89\xef\x49\xd2\xfa\xe5\x72\xb8" "\x81\xb1\x23\xa8\x5f\xfa\x21\x59\x5f\x36" }, { GCRY_MD_RMD160, "Libgcrypt is free software; you can redistribute it and/or modif" "y it under the terms of the GNU Lesser general Public License as" " published by the Free Software Foundation; either version 2.1 o" "f the License, or (at your option) any later version.\nLibgcrypt" " is distributed in the hope that it will be useful, but WITHOUT " "ANY WARRANTY; without even the implied warranty of MERCHANTABILI" "TY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser Gene" "ral Public License for more details.", "\x06\x6d\x3c\x4e\xc9\xba\x89\x75\x16\x90\x96\x4e\xfd\x43\x07\xde" "\x04\xca\x69\x6b" }, { GCRY_MD_RMD160, "!", "\x52\x78\x32\x43\xc1\x69\x7b\xdb\xe1\x6d\x37\xf9\x7f\x68\xf0\x83" "\x25\xdc\x15\x28" }, { GCRY_MD_RMD160, "?", "\x68\x14\x86\x70\x3d\x51\x4e\x36\x68\x50\xf8\xb3\x00\x75\xda\x49" "\x0a\xaa\x2c\xf6" }, { GCRY_MD_CRC32, "", "\x00\x00\x00\x00" }, { GCRY_MD_CRC32, "foo", "\x8c\x73\x65\x21" }, { GCRY_MD_CRC32, "Libgcrypt is free software; you can redistribute it and/or modif" "y it under the terms of the GNU Lesser general Public License as" " published by the Free Software Foundation; either version 2.1 o" "f the License, or (at your option) any later version.\nLibgcrypt" " is distributed in the hope that it will be useful, but WITHOUT " "ANY WARRANTY; without even the implied warranty of MERCHANTABILI" "TY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser Gene" "ral Public License for more details.", "\x4A\x53\x7D\x67" }, { GCRY_MD_CRC32, "123456789", "\xcb\xf4\x39\x26" }, { GCRY_MD_CRC32, "!", "\xdc\x25\xbf\xbc" }, { GCRY_MD_CRC32, "?", "\x61\x82\x29\x1B" }, { GCRY_MD_CRC32_RFC1510, "", "\x00\x00\x00\x00" }, { GCRY_MD_CRC32_RFC1510, "foo", "\x73\x32\xbc\x33" }, { GCRY_MD_CRC32_RFC1510, "test0123456789", "\xb8\x3e\x88\xd6" }, { GCRY_MD_CRC32_RFC1510, "MASSACHVSETTS INSTITVTE OF TECHNOLOGY", "\xe3\x41\x80\xf7" }, { GCRY_MD_CRC32_RFC1510, "\x80\x00", "\x3b\x83\x98\x4b", 2 }, { GCRY_MD_CRC32_RFC1510, "\x00\x08", "\x0e\xdb\x88\x32", 2 }, { GCRY_MD_CRC32_RFC1510, "\x00\x80", "\xed\xb8\x83\x20", 2 }, { GCRY_MD_CRC32_RFC1510, "\x80", "\xed\xb8\x83\x20" }, { GCRY_MD_CRC32_RFC1510, "\x80\x00\x00\x00", "\xed\x59\xb6\x3b", 4 }, { GCRY_MD_CRC32_RFC1510, "\x00\x00\x00\x01", "\x77\x07\x30\x96", 4 }, { GCRY_MD_CRC32_RFC1510, "123456789", "\x2d\xfd\x2d\x88" }, { GCRY_MD_CRC32_RFC1510, "!", "\xce\x5c\x74\x22" }, { GCRY_MD_CRC32_RFC1510, "?", "\x73\xfb\xe2\x85" }, { GCRY_MD_CRC24_RFC2440, "", "\xb7\x04\xce" }, { GCRY_MD_CRC24_RFC2440, "foo", "\x4f\xc2\x55" }, { GCRY_MD_CRC24_RFC2440, "123456789", "\x21\xcf\x02" }, { GCRY_MD_CRC24_RFC2440, "!", "\xa5\xcb\x6b" }, { GCRY_MD_CRC24_RFC2440, "?", "\x7f\x67\x03" }, { GCRY_MD_TIGER, "", "\x24\xF0\x13\x0C\x63\xAC\x93\x32\x16\x16\x6E\x76" "\xB1\xBB\x92\x5F\xF3\x73\xDE\x2D\x49\x58\x4E\x7A" }, { GCRY_MD_TIGER, "abc", "\xF2\x58\xC1\xE8\x84\x14\xAB\x2A\x52\x7A\xB5\x41" "\xFF\xC5\xB8\xBF\x93\x5F\x7B\x95\x1C\x13\x29\x51" }, { GCRY_MD_TIGER, "Tiger", "\x9F\x00\xF5\x99\x07\x23\x00\xDD\x27\x6A\xBB\x38" "\xC8\xEB\x6D\xEC\x37\x79\x0C\x11\x6F\x9D\x2B\xDF" }, { GCRY_MD_TIGER, "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefg" "hijklmnopqrstuvwxyz0123456789+-", "\x87\xFB\x2A\x90\x83\x85\x1C\xF7\x47\x0D\x2C\xF8" "\x10\xE6\xDF\x9E\xB5\x86\x44\x50\x34\xA5\xA3\x86" }, { GCRY_MD_TIGER, "ABCDEFGHIJKLMNOPQRSTUVWXYZ=abcdef" "ghijklmnopqrstuvwxyz+0123456789", "\x46\x7D\xB8\x08\x63\xEB\xCE\x48\x8D\xF1\xCD\x12" "\x61\x65\x5D\xE9\x57\x89\x65\x65\x97\x5F\x91\x97" }, { GCRY_MD_TIGER, "Tiger - A Fast New Hash Function, " "by Ross Anderson and Eli Biham", "\x0C\x41\x0A\x04\x29\x68\x86\x8A\x16\x71\xDA\x5A" "\x3F\xD2\x9A\x72\x5E\xC1\xE4\x57\xD3\xCD\xB3\x03" }, { GCRY_MD_TIGER, "Tiger - A Fast New Hash Function, " "by Ross Anderson and Eli Biham, proceedings of Fa" "st Software Encryption 3, Cambridge.", "\xEB\xF5\x91\xD5\xAF\xA6\x55\xCE\x7F\x22\x89\x4F" "\xF8\x7F\x54\xAC\x89\xC8\x11\xB6\xB0\xDA\x31\x93" }, { GCRY_MD_TIGER, "Tiger - A Fast New Hash Function, " "by Ross Anderson and Eli Biham, proceedings of Fa" "st Software Encryption 3, Cambridge, 1996.", "\x3D\x9A\xEB\x03\xD1\xBD\x1A\x63\x57\xB2\x77\x4D" "\xFD\x6D\x5B\x24\xDD\x68\x15\x1D\x50\x39\x74\xFC" }, { GCRY_MD_TIGER, "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefgh" "ijklmnopqrstuvwxyz0123456789+-ABCDEFGHIJKLMNOPQRS" "TUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-", "\x00\xB8\x3E\xB4\xE5\x34\x40\xC5\x76\xAC\x6A\xAE" "\xE0\xA7\x48\x58\x25\xFD\x15\xE7\x0A\x59\xFF\xE4" }, { GCRY_MD_TIGER1, "", "\x32\x93\xAC\x63\x0C\x13\xF0\x24\x5F\x92\xBB\xB1" "\x76\x6E\x16\x16\x7A\x4E\x58\x49\x2D\xDE\x73\xF3" }, { GCRY_MD_TIGER1, "a", "\x77\xBE\xFB\xEF\x2E\x7E\xF8\xAB\x2E\xC8\xF9\x3B" "\xF5\x87\xA7\xFC\x61\x3E\x24\x7F\x5F\x24\x78\x09" }, { GCRY_MD_TIGER1, "abc", "\x2A\xAB\x14\x84\xE8\xC1\x58\xF2\xBF\xB8\xC5\xFF" "\x41\xB5\x7A\x52\x51\x29\x13\x1C\x95\x7B\x5F\x93" }, { GCRY_MD_TIGER1, "message digest", "\xD9\x81\xF8\xCB\x78\x20\x1A\x95\x0D\xCF\x30\x48" "\x75\x1E\x44\x1C\x51\x7F\xCA\x1A\xA5\x5A\x29\xF6" }, { GCRY_MD_TIGER1, "abcdefghijklmnopqrstuvwxyz", "\x17\x14\xA4\x72\xEE\xE5\x7D\x30\x04\x04\x12\xBF" "\xCC\x55\x03\x2A\x0B\x11\x60\x2F\xF3\x7B\xEE\xE9" }, { GCRY_MD_TIGER1, "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", "\x0F\x7B\xF9\xA1\x9B\x9C\x58\xF2\xB7\x61\x0D\xF7" "\xE8\x4F\x0A\xC3\xA7\x1C\x63\x1E\x7B\x53\xF7\x8E" }, { GCRY_MD_TIGER1, "ABCDEFGHIJKLMNOPQRSTUVWXYZ" "abcdefghijklmnopqrstuvwxyz" "0123456789", "\x8D\xCE\xA6\x80\xA1\x75\x83\xEE\x50\x2B\xA3\x8A" "\x3C\x36\x86\x51\x89\x0F\xFB\xCC\xDC\x49\xA8\xCC" }, { GCRY_MD_TIGER1, "1234567890" "1234567890" "1234567890" "1234567890" "1234567890" "1234567890" "1234567890" "1234567890", "\x1C\x14\x79\x55\x29\xFD\x9F\x20\x7A\x95\x8F\x84" "\xC5\x2F\x11\xE8\x87\xFA\x0C\xAB\xDF\xD9\x1B\xFD" }, { GCRY_MD_TIGER1, "!", "\x6D\xB0\xE2\x72\x9C\xBE\xAD\x93\xD7\x15\xC6\xA7" "\xD3\x63\x02\xE9\xB3\xCE\xE0\xD2\xBC\x31\x4B\x41" }, { GCRY_MD_TIGER1, "Libgcrypt is free software; you can redistribute it and/or modif" "y it under the terms of the GNU Lesser general Public License as" " published by the Free Software Foundation; either version 2.1 o" "f the License, or (at your option) any later version.\nLibgcrypt" " is distributed in the hope that it will be useful, but WITHOUT " "ANY WARRANTY; without even the implied warranty of MERCHANTABILI" "TY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser Gene" "ral Public License for more details.", "\x60\xee\xdf\x95\x39\xc8\x44\x94\x64\xdc\xdf\x3d\x2e\x1c\xe5\x79" "\x6a\x95\xbd\x30\x68\x8c\x7e\xb8" }, { GCRY_MD_TIGER1, "?", "\x4b\xe2\x3f\x23\xf5\x34\xbe\xbf\x97\x42\x95\x80" "\x54\xe4\x6c\x12\x64\x85\x44\x0a\xa9\x49\x9b\x65" }, { GCRY_MD_TIGER2, "", "\x44\x41\xBE\x75\xF6\x01\x87\x73\xC2\x06\xC2\x27" "\x45\x37\x4B\x92\x4A\xA8\x31\x3F\xEF\x91\x9F\x41" }, { GCRY_MD_TIGER2, "a", "\x67\xE6\xAE\x8E\x9E\x96\x89\x99\xF7\x0A\x23\xE7" "\x2A\xEA\xA9\x25\x1C\xBC\x7C\x78\xA7\x91\x66\x36" }, { GCRY_MD_TIGER2, "abc", "\xF6\x8D\x7B\xC5\xAF\x4B\x43\xA0\x6E\x04\x8D\x78" "\x29\x56\x0D\x4A\x94\x15\x65\x8B\xB0\xB1\xF3\xBF" }, { GCRY_MD_TIGER2, "message digest", "\xE2\x94\x19\xA1\xB5\xFA\x25\x9D\xE8\x00\x5E\x7D" "\xE7\x50\x78\xEA\x81\xA5\x42\xEF\x25\x52\x46\x2D" }, { GCRY_MD_TIGER2, "abcdefghijklmnopqrstuvwxyz", "\xF5\xB6\xB6\xA7\x8C\x40\x5C\x85\x47\xE9\x1C\xD8" "\x62\x4C\xB8\xBE\x83\xFC\x80\x4A\x47\x44\x88\xFD" }, { GCRY_MD_TIGER2, "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", "\xA6\x73\x7F\x39\x97\xE8\xFB\xB6\x3D\x20\xD2\xDF" "\x88\xF8\x63\x76\xB5\xFE\x2D\x5C\xE3\x66\x46\xA9" }, { GCRY_MD_TIGER2, "ABCDEFGHIJKLMNOPQRSTUVWXYZ" "abcdefghijklmnopqrstuvwxyz" "0123456789", "\xEA\x9A\xB6\x22\x8C\xEE\x7B\x51\xB7\x75\x44\xFC" "\xA6\x06\x6C\x8C\xBB\x5B\xBA\xE6\x31\x95\x05\xCD" }, { GCRY_MD_TIGER2, "1234567890" "1234567890" "1234567890" "1234567890" "1234567890" "1234567890" "1234567890" "1234567890", "\xD8\x52\x78\x11\x53\x29\xEB\xAA\x0E\xEC\x85\xEC" "\xDC\x53\x96\xFD\xA8\xAA\x3A\x58\x20\x94\x2F\xFF" }, { GCRY_MD_TIGER2, "!", "\xE0\x68\x28\x1F\x06\x0F\x55\x16\x28\xCC\x57\x15" "\xB9\xD0\x22\x67\x96\x91\x4D\x45\xF7\x71\x7C\xF4" }, { GCRY_MD_WHIRLPOOL, "", "\x19\xFA\x61\xD7\x55\x22\xA4\x66\x9B\x44\xE3\x9C\x1D\x2E\x17\x26" "\xC5\x30\x23\x21\x30\xD4\x07\xF8\x9A\xFE\xE0\x96\x49\x97\xF7\xA7" "\x3E\x83\xBE\x69\x8B\x28\x8F\xEB\xCF\x88\xE3\xE0\x3C\x4F\x07\x57" "\xEA\x89\x64\xE5\x9B\x63\xD9\x37\x08\xB1\x38\xCC\x42\xA6\x6E\xB3" }, { GCRY_MD_WHIRLPOOL, "a", "\x8A\xCA\x26\x02\x79\x2A\xEC\x6F\x11\xA6\x72\x06\x53\x1F\xB7\xD7" "\xF0\xDF\xF5\x94\x13\x14\x5E\x69\x73\xC4\x50\x01\xD0\x08\x7B\x42" "\xD1\x1B\xC6\x45\x41\x3A\xEF\xF6\x3A\x42\x39\x1A\x39\x14\x5A\x59" "\x1A\x92\x20\x0D\x56\x01\x95\xE5\x3B\x47\x85\x84\xFD\xAE\x23\x1A" }, { GCRY_MD_WHIRLPOOL, "?", "\x88\xf0\x78\x6d\x0d\x47\xe5\x32\x1f\x88\xb1\x48\x05\x53\x58\x7d" "\x19\x4b\x32\x9b\xf1\xfb\x17\xc5\x98\x3a\x87\xa2\x48\x61\x3d\x2b" "\xb2\xbc\x9f\x0d\xd2\x14\x37\x30\x55\x30\x91\xa7\xb8\x0c\x0f\x80" "\x7c\x7b\x94\xf6\x55\xf6\x0b\x12\x85\x0c\x8e\x6d\x17\x5b\x1e\x71" }, { GCRY_MD_WHIRLPOOL, "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", "\xDC\x37\xE0\x08\xCF\x9E\xE6\x9B\xF1\x1F\x00\xED\x9A\xBA\x26\x90" "\x1D\xD7\xC2\x8C\xDE\xC0\x66\xCC\x6A\xF4\x2E\x40\xF8\x2F\x3A\x1E" "\x08\xEB\xA2\x66\x29\x12\x9D\x8F\xB7\xCB\x57\x21\x1B\x92\x81\xA6" "\x55\x17\xCC\x87\x9D\x7B\x96\x21\x42\xC6\x5F\x5A\x7A\xF0\x14\x67" }, { GCRY_MD_WHIRLPOOL, "!", "\x0C\x99\x00\x5B\xEB\x57\xEF\xF5\x0A\x7C\xF0\x05\x56\x0D\xDF\x5D" "\x29\x05\x7F\xD8\x6B\x20\xBF\xD6\x2D\xEC\xA0\xF1\xCC\xEA\x4A\xF5" "\x1F\xC1\x54\x90\xED\xDC\x47\xAF\x32\xBB\x2B\x66\xC3\x4F\xF9\xAD" "\x8C\x60\x08\xAD\x67\x7F\x77\x12\x69\x53\xB2\x26\xE4\xED\x8B\x01" }, { GCRY_MD_WHIRLPOOL, "Libgcrypt is free software; you can redistribute it and/or modif" "y it under the terms of the GNU Lesser general Public License as" " published by the Free Software Foundation; either version 2.1 o" "f the License, or (at your option) any later version.\nLibgcrypt" " is distributed in the hope that it will be useful, but WITHOUT " "ANY WARRANTY; without even the implied warranty of MERCHANTABILI" "TY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser Gene" "ral Public License for more details.", "\xcd\x4a\xa4\xaf\xf6\x7f\xec\xce\xbb\x6c\xdf\x91\x96\xe1\xf3\xf6" "\x78\xe2\x8e\x3a\x76\xcf\x06\xc7\xa1\x20\x7b\x81\x32\x60\xf7\x8e" "\x68\x19\x62\x33\x4f\xe5\x0a\x24\xfb\x9e\x74\x03\x74\xe4\x61\x29" "\x6f\xb3\x13\xe6\x7e\xc2\x88\x99\x9e\xfb\xe7\x9d\x11\x30\x89\xd2" }, { GCRY_MD_GOSTR3411_94, "This is message, length=32 bytes", "\xB1\xC4\x66\xD3\x75\x19\xB8\x2E\x83\x19\x81\x9F\xF3\x25\x95\xE0" "\x47\xA2\x8C\xB6\xF8\x3E\xFF\x1C\x69\x16\xA8\x15\xA6\x37\xFF\xFA" }, { GCRY_MD_GOSTR3411_94, "Suppose the original message has length = 50 bytes", "\x47\x1A\xBA\x57\xA6\x0A\x77\x0D\x3A\x76\x13\x06\x35\xC1\xFB\xEA" "\x4E\xF1\x4D\xE5\x1F\x78\xB4\xAE\x57\xDD\x89\x3B\x62\xF5\x52\x08" }, { GCRY_MD_GOSTR3411_94, "", "\xCE\x85\xB9\x9C\xC4\x67\x52\xFF\xFE\xE3\x5C\xAB\x9A\x7B\x02\x78" "\xAB\xB4\xC2\xD2\x05\x5C\xFF\x68\x5A\xF4\x91\x2C\x49\x49\x0F\x8D" }, { GCRY_MD_GOSTR3411_94, "!", "\x5C\x00\xCC\xC2\x73\x4C\xDD\x33\x32\xD3\xD4\x74\x95\x76\xE3\xC1" "\xA7\xDB\xAF\x0E\x7E\xA7\x4E\x9F\xA6\x02\x41\x3C\x90\xA1\x29\xFA" }, { GCRY_MD_GOSTR3411_94, "Libgcrypt is free software; you can redistribute it and/or modif" "y it under the terms of the GNU Lesser general Public License as" " published by the Free Software Foundation; either version 2.1 o" "f the License, or (at your option) any later version.\nLibgcrypt" " is distributed in the hope that it will be useful, but WITHOUT " "ANY WARRANTY; without even the implied warranty of MERCHANTABILI" "TY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser Gene" "ral Public License for more details.", "\x00\x0c\x85\xc8\x54\xd2\x9a\x6e\x47\x2e\xff\xa4\xa2\xe7\xd0\x2e" "\x8a\xcc\x14\x53\xb4\x87\xc8\x5c\x95\x9a\x3e\x85\x8c\x7d\x6e\x0c" }, { GCRY_MD_STRIBOG512, "012345678901234567890123456789012345678901234567890123456789012", "\x1b\x54\xd0\x1a\x4a\xf5\xb9\xd5\xcc\x3d\x86\xd6\x8d\x28\x54\x62" "\xb1\x9a\xbc\x24\x75\x22\x2f\x35\xc0\x85\x12\x2b\xe4\xba\x1f\xfa" "\x00\xad\x30\xf8\x76\x7b\x3a\x82\x38\x4c\x65\x74\xf0\x24\xc3\x11" "\xe2\xa4\x81\x33\x2b\x08\xef\x7f\x41\x79\x78\x91\xc1\x64\x6f\x48" }, { GCRY_MD_STRIBOG256, "012345678901234567890123456789012345678901234567890123456789012", "\x9d\x15\x1e\xef\xd8\x59\x0b\x89\xda\xa6\xba\x6c\xb7\x4a\xf9\x27" "\x5d\xd0\x51\x02\x6b\xb1\x49\xa4\x52\xfd\x84\xe5\xe5\x7b\x55\x00" }, { GCRY_MD_STRIBOG512, "\xd1\xe5\x20\xe2\xe5\xf2\xf0\xe8\x2c\x20\xd1\xf2\xf0\xe8\xe1\xee" "\xe6\xe8\x20\xe2\xed\xf3\xf6\xe8\x2c\x20\xe2\xe5\xfe\xf2\xfa\x20" "\xf1\x20\xec\xee\xf0\xff\x20\xf1\xf2\xf0\xe5\xeb\xe0\xec\xe8\x20" "\xed\xe0\x20\xf5\xf0\xe0\xe1\xf0\xfb\xff\x20\xef\xeb\xfa\xea\xfb" "\x20\xc8\xe3\xee\xf0\xe5\xe2\xfb", "\x1e\x88\xe6\x22\x26\xbf\xca\x6f\x99\x94\xf1\xf2\xd5\x15\x69\xe0" "\xda\xf8\x47\x5a\x3b\x0f\xe6\x1a\x53\x00\xee\xe4\x6d\x96\x13\x76" "\x03\x5f\xe8\x35\x49\xad\xa2\xb8\x62\x0f\xcd\x7c\x49\x6c\xe5\xb3" "\x3f\x0c\xb9\xdd\xdc\x2b\x64\x60\x14\x3b\x03\xda\xba\xc9\xfb\x28" }, { GCRY_MD_STRIBOG256, "\xd1\xe5\x20\xe2\xe5\xf2\xf0\xe8\x2c\x20\xd1\xf2\xf0\xe8\xe1\xee" "\xe6\xe8\x20\xe2\xed\xf3\xf6\xe8\x2c\x20\xe2\xe5\xfe\xf2\xfa\x20" "\xf1\x20\xec\xee\xf0\xff\x20\xf1\xf2\xf0\xe5\xeb\xe0\xec\xe8\x20" "\xed\xe0\x20\xf5\xf0\xe0\xe1\xf0\xfb\xff\x20\xef\xeb\xfa\xea\xfb" "\x20\xc8\xe3\xee\xf0\xe5\xe2\xfb", "\x9d\xd2\xfe\x4e\x90\x40\x9e\x5d\xa8\x7f\x53\x97\x6d\x74\x05\xb0" "\xc0\xca\xc6\x28\xfc\x66\x9a\x74\x1d\x50\x06\x3c\x55\x7e\x8f\x50" }, /* Special tests for carry flag in addition */ { GCRY_MD_STRIBOG512, "\xEE\xEE\xEE\xEE\xEE\xEE\xEE\xEE\xEE\xEE\xEE\xEE\xEE\xEE\xEE\xEE" "\xEE\xEE\xEE\xEE\xEE\xEE\xEE\xEE\xEE\xEE\xEE\xEE\xEE\xEE\xEE\xEE" "\xEE\xEE\xEE\xEE\xEE\xEE\xEE\xEE\xEE\xEE\xEE\xEE\xEE\xEE\xEE\xEE" "\xEE\xEE\xEE\xEE\xEE\xEE\xEE\xEE\xEE\xEE\xEE\xEE\xEE\xEE\xEE\xEE" "\x16\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11" "\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11" "\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11" "\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x16", "\x8b\x06\xf4\x1e\x59\x90\x7d\x96\x36\xe8\x92\xca\xf5\x94\x2f\xcd" "\xfb\x71\xfa\x31\x16\x9a\x5e\x70\xf0\xed\xb8\x73\x66\x4d\xf4\x1c" "\x2c\xce\x6e\x06\xdc\x67\x55\xd1\x5a\x61\xcd\xeb\x92\xbd\x60\x7c" "\xc4\xaa\xca\x67\x32\xbf\x35\x68\xa2\x3a\x21\x0d\xd5\x20\xfd\x41" }, { GCRY_MD_STRIBOG512, "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff", "\x90\xa1\x61\xd1\x2a\xd3\x09\x49\x8d\x3f\xe5\xd4\x82\x02\xd8\xa4" "\xe9\xc4\x06\xd6\xa2\x64\xae\xab\x25\x8a\xc5\xec\xc3\x7a\x79\x62" "\xaa\xf9\x58\x7a\x5a\xbb\x09\xb6\xbb\x81\xec\x4b\x37\x52\xa3\xff" "\x5a\x83\x8e\xf1\x75\xbe\x57\x72\x05\x6b\xc5\xfe\x54\xfc\xfc\x7e" }, #include "./sha3-224.h" #include "./sha3-256.h" #include "./sha3-384.h" #include "./sha3-512.h" { GCRY_MD_SHAKE128, "", "\x7F\x9C\x2B\xA4\xE8\x8F\x82\x7D\x61\x60\x45\x50\x76\x05\x85\x3E" "\xD7\x3B\x80\x93\xF6\xEF\xBC\x88\xEB\x1A\x6E\xAC\xFA\x66\xEF\x26" "\x3C\xB1\xEE\xA9\x88\x00\x4B\x93\x10\x3C\xFB\x0A\xEE\xFD\x2A\x68" "\x6E\x01\xFA\x4A\x58\xE8\xA3\x63\x9C\xA8\xA1\xE3\xF9\xAE\x57\xE2" "\x35\xB8\xCC\x87\x3C\x23\xDC\x62\xB8\xD2\x60\x16\x9A\xFA\x2F\x75" "\xAB\x91\x6A\x58\xD9\x74\x91\x88\x35\xD2\x5E\x6A\x43\x50\x85\xB2" "\xBA\xDF\xD6\xDF\xAA\xC3\x59\xA5\xEF\xBB\x7B\xCC\x4B\x59\xD5\x38" "\xDF\x9A\x04\x30\x2E\x10\xC8\xBC\x1C\xBF\x1A\x0B\x3A\x51\x20\xEA" "\x17\xCD\xA7\xCF\xAD\x76\x5F\x56\x23\x47\x4D\x36\x8C\xCC\xA8\xAF" "\x00\x07\xCD\x9F\x5E\x4C\x84\x9F\x16\x7A\x58\x0B\x14\xAA\xBD\xEF" "\xAE\xE7\xEE\xF4\x7C\xB0\xFC\xA9\x76\x7B\xE1\xFD\xA6\x94\x19\xDF" "\xB9\x27\xE9\xDF\x07\x34\x8B\x19\x66\x91\xAB\xAE\xB5\x80\xB3\x2D" "\xEF\x58\x53\x8B\x8D\x23\xF8\x77\x32\xEA\x63\xB0\x2B\x4F\xA0\xF4" "\x87\x33\x60\xE2\x84\x19\x28\xCD\x60\xDD\x4C\xEE\x8C\xC0\xD4\xC9" "\x22\xA9\x61\x88\xD0\x32\x67\x5C\x8A\xC8\x50\x93\x3C\x7A\xFF\x15" "\x33\xB9\x4C\x83\x4A\xDB\xB6\x9C\x61\x15\xBA\xD4\x69\x2D\x86\x19" "\xF9\x0B\x0C\xDF\x8A\x7B\x9C\x26\x40\x29\xAC\x18\x5B\x70\xB8\x3F" "\x28\x01\xF2\xF4\xB3\xF7\x0C\x59\x3E\xA3\xAE\xEB\x61\x3A\x7F\x1B" "\x1D\xE3\x3F\xD7\x50\x81\xF5\x92\x30\x5F\x2E\x45\x26\xED\xC0\x96" "\x31\xB1\x09\x58\xF4\x64\xD8\x89\xF3\x1B\xA0\x10\x25\x0F\xDA\x7F" "\x13\x68\xEC\x29\x67\xFC\x84\xEF\x2A\xE9\xAF\xF2\x68\xE0\xB1\x70" "\x0A\xFF\xC6\x82\x0B\x52\x3A\x3D\x91\x71\x35\xF2\xDF\xF2\xEE\x06" "\xBF\xE7\x2B\x31\x24\x72\x1D\x4A\x26\xC0\x4E\x53\xA7\x5E\x30\xE7" "\x3A\x7A\x9C\x4A\x95\xD9\x1C\x55\xD4\x95\xE9\xF5\x1D\xD0\xB5\xE9" "\xD8\x3C\x6D\x5E\x8C\xE8\x03\xAA\x62\xB8\xD6\x54\xDB\x53\xD0\x9B" "\x8D\xCF\xF2\x73\xCD\xFE\xB5\x73\xFA\xD8\xBC\xD4\x55\x78\xBE\xC2" "\xE7\x70\xD0\x1E\xFD\xE8\x6E\x72\x1A\x3F\x7C\x6C\xCE\x27\x5D\xAB" "\xE6\xE2\x14\x3F\x1A\xF1\x8D\xA7\xEF\xDD\xC4\xC7\xB7\x0B\x5E\x34" "\x5D\xB9\x3C\xC9\x36\xBE\xA3\x23\x49\x1C\xCB\x38\xA3\x88\xF5\x46" "\xA9\xFF\x00\xDD\x4E\x13\x00\xB9\xB2\x15\x3D\x20\x41\xD2\x05\xB4" "\x43\xE4\x1B\x45\xA6\x53\xF2\xA5\xC4\x49\x2C\x1A\xDD\x54\x45\x12" "\xDD\xA2\x52\x98\x33\x46\x2B\x71\xA4\x1A\x45\xBE\x97\x29\x0B\x6F", 0, 512, }, { GCRY_MD_SHAKE128, "\x5A\xAB\x62\x75\x6D\x30\x7A\x66\x9D\x14\x6A\xBA\x98\x8D\x90\x74" "\xC5\xA1\x59\xB3\xDE\x85\x15\x1A\x81\x9B\x11\x7C\xA1\xFF\x65\x97" "\xF6\x15\x6E\x80\xFD\xD2\x8C\x9C\x31\x76\x83\x51\x64\xD3\x7D\xA7" "\xDA\x11\xD9\x4E\x09\xAD\xD7\x70\xB6\x8A\x6E\x08\x1C\xD2\x2C\xA0" "\xC0\x04\xBF\xE7\xCD\x28\x3B\xF4\x3A\x58\x8D\xA9\x1F\x50\x9B\x27" "\xA6\x58\x4C\x47\x4A\x4A\x2F\x3E\xE0\xF1\xF5\x64\x47\x37\x92\x40" "\xA5\xAB\x1F\xB7\x7F\xDC\xA4\x9B\x30\x5F\x07\xBA\x86\xB6\x27\x56" "\xFB\x9E\xFB\x4F\xC2\x25\xC8\x68\x45\xF0\x26\xEA\x54\x20\x76\xB9" "\x1A\x0B\xC2\xCD\xD1\x36\xE1\x22\xC6\x59\xBE\x25\x9D\x98\xE5\x84" "\x1D\xF4\xC2\xF6\x03\x30\xD4\xD8\xCD\xEE\x7B\xF1\xA0\xA2\x44\x52" "\x4E\xEC\xC6\x8F\xF2\xAE\xF5\xBF\x00\x69\xC9\xE8\x7A\x11\xC6\xE5" "\x19\xDE\x1A\x40\x62\xA1\x0C\x83\x83\x73\x88\xF7\xEF\x58\x59\x8A" "\x38\x46\xF4\x9D\x49\x96\x82\xB6\x83\xC4\xA0\x62\xB4\x21\x59\x4F" "\xAF\xBC\x13\x83\xC9\x43\xBA\x83\xBD\xEF\x51\x5E\xFC\xF1\x0D", "\xF0\x71\x5D\xE3\x56\x92\xFD\x70\x12\x3D\xC6\x83\x68\xD0\xFE\xEC" "\x06\xA0\xC7\x4C\xF8\xAD\xB0\x5D\xDC\x25\x54\x87\xB1\xA8\xD4\xD1" "\x21\x3E\x9E\xAB\xAF\x41\xF1\x16\x17\x19\xD0\x65\xD7\x94\xB7\x50" "\xF8\x4B\xE3\x2A\x32\x34\xB4\xD5\x36\x46\x0D\x55\x20\x68\x8A\x5A" "\x79\xA1\x7A\x4B\xA8\x98\x7F\xCB\x61\xBF\x7D\xAA\x8B\x54\x7B\xF5" "\xC1\xCE\x36\xB5\x6A\x73\x25\x7D\xBB\xF1\xBA\xBB\x64\xF2\x49\xBD" "\xCE\xB6\x7B\xA1\xC8\x88\x37\x0A\x96\x3D\xFD\x6B\x6A\x2A\xDE\x2C" "\xEF\xD1\x4C\x32\x52\xCB\x37\x58\x52\x0F\x0C\x65\xF4\x52\x46\x82" "\x77\x24\x99\x46\x3A\xE1\xA3\x41\x80\x01\x83\xAA\x60\xEF\xA0\x51" "\x18\xA2\x82\x01\x74\x4F\x7B\xA0\xB0\xA3\x92\x8D\xD7\xC0\x26\x3F" "\xD2\x64\xB7\xCD\x7B\x2E\x2E\x09\xB3\x22\xBF\xCE\xA8\xEE\xD0\x42" "\x75\x79\x5B\xE7\xC0\xF0\x0E\x11\x38\x27\x37\x0D\x05\x1D\x50\x26" "\x95\x80\x30\x00\x05\xAC\x12\x88\xFE\xA6\xCD\x9A\xE9\xF4\xF3\x7C" "\xE0\xF8\xAC\xE8\xBF\x3E\xBE\x1D\x70\x56\x25\x59\x54\xC7\x61\x93" "\x1D\x3C\x42\xED\x62\xF7\xF1\xCE\x1B\x94\x5C\xDE\xCC\x0A\x74\x32" "\x2D\x7F\x64\xD6\x00\x4F\xF2\x16\x84\x14\x93\x07\x28\x8B\x44\x8E" "\x45\x43\x34\x75\xB1\xEA\x13\x14\xB0\x0F\x1F\xC4\x50\x08\x9A\x9D" "\x1F\x77\x10\xC6\xD7\x65\x2E\xCF\x65\x4F\x3B\x48\x7D\x02\x83\xD4" "\xD8\xA2\x8E\xFB\x50\x66\xC4\x25\x0D\x5A\xD6\x98\xE1\x5D\xBA\x88" "\xE9\x25\xE4\xDE\x99\xB6\x9B\xC3\x83\xAC\x80\x45\xB7\xF1\x02\x2A" "\xDD\x39\xD4\x43\x54\x6A\xE0\x92\x4F\x13\xF4\x89\x60\x96\xDF\xDF" "\x37\xCA\x72\x20\x79\x87\xC4\xA7\x70\x5A\x7A\xBE\x72\x4B\x7F\xA1" "\x0C\x90\x9F\x39\x25\x44\x9F\x01\x0D\x61\xE2\x07\xAD\xD9\x52\x19" "\x07\x1A\xCE\xED\xB9\xB9\xDC\xED\x32\xA9\xE1\x23\x56\x1D\x60\x82" "\xD4\x6A\xEF\xAE\x07\xEE\x1B\xD1\x32\x76\x5E\x3E\x51\x3C\x66\x50" "\x1B\x38\x7A\xB2\xEE\x09\xA0\x4A\xE6\x3E\x25\x80\x85\x17\xAF\xEA" "\x3E\x05\x11\x69\xCF\xD2\xFF\xF8\xC5\x85\x8E\x2D\x96\x23\x89\x7C" "\x9E\x85\x17\x5A\xC5\xA8\x63\x94\xCD\x0A\x32\xA0\xA6\x2A\x8F\x5D" "\x6C\xCC\xBF\x49\x3D\xAA\x43\xF7\x83\x62\xBB\xCA\x40\xAD\xF7\x33" "\xF8\x71\xE0\xC0\x09\x98\xD9\xBF\xD6\x88\x06\x56\x66\x6C\xD7\xBE" "\x4F\xE9\x89\x2C\x61\xDC\xD5\xCD\x23\xA5\xE4\x27\x7E\xEE\x8B\x4A" "\xFD\x29\xB6\x9B\xBA\x55\x66\x0A\x21\x71\x12\xFF\x6E\x34\x56\xB1", 223, 512, }, { GCRY_MD_SHAKE128, "!", "\x9d\x22\x2c\x79\xc4\xff\x9d\x09\x2c\xf6\xca\x86\x14\x3a\xa4\x11" "\xe3\x69\x97\x38\x08\xef\x97\x09\x32\x55\x82\x6c\x55\x72\xef\x58" "\x42\x4c\x4b\x5c\x28\x47\x5f\xfd\xcf\x98\x16\x63\x86\x7f\xec\x63" "\x21\xc1\x26\x2e\x38\x7b\xcc\xf8\xca\x67\x68\x84\xc4\xa9\xd0\xc1" "\x3b\xfa\x68\x69\x76\x3d\x5a\xe4\xbb\xc9\xb3\xcc\xd0\x9d\x1c\xa5" "\xea\x74\x46\x53\x8d\x69\xb3\xfb\x98\xc7\x2b\x59\xa2\xb4\x81\x7d" "\xb5\xea\xdd\x90\x11\xf9\x0f\xa7\x10\x91\x93\x1f\x81\x34\xf4\xf0" "\x0b\x56\x2e\x2f\xe1\x05\x93\x72\x70\x36\x1c\x19\x09\x86\x2a\xd4" "\x50\x46\xe3\x93\x2f\x5d\xd3\x11\xec\x72\xfe\xc5\xf8\xfb\x8f\x60" "\xb4\x5a\x3b\xee\x3f\x85\xbb\xf7\xfc\xed\xc6\xa5\x55\x67\x76\x48" "\xe0\x65\x4b\x38\x19\x41\xa8\x6b\xd3\xe5\x12\x65\x7b\x0d\x57\xa7" "\x99\x1f\xc4\x54\x3f\x89\xd8\x29\x04\x92\x22\x2c\xe4\xa3\x3e\x17" "\x60\x2b\x3b\x99\xc0\x09\xf7\x65\x5f\x87\x53\x5c\xda\xa3\x71\x6f" "\x58\xc4\x7b\x8a\x15\x7a\xd1\x95\xf0\x28\x09\xf2\x75\x00\xb9\x25" "\x49\x79\x31\x1c\x6b\xb4\x15\x96\x8c\xd1\x04\x31\x16\x9a\x27\xd5" "\xa8\xd6\x1e\x13\xa6\xb8\xb7\x7a\xf1\xf8\xb6\xdd\x2e\xef\xde\xa0" "\x40\x78\x96\x80\x49\x0b\x5e\xdc\xb1\xd3\xe5\x38\xa4\x66\xf7\x57" "\xad\x71\x8f\xe1\xfd\x9f\xae\xef\xa4\x72\x46\xad\x5e\x36\x7f\x87" "\xd3\xb4\x85\x0d\x44\x86\xeb\x21\x99\xe9\x4a\x79\x79\xe2\x09\x1a" "\xbc\xdf\x3b\xc1\x33\x79\xc8\x96\xdc\xeb\x79\xa8\xfd\x08\xf1\x10" "\x73\xf3\x3e\x3f\x99\x23\x22\xb3\x12\x02\xde\xe2\x34\x33\x0c\xf3" "\x30\x4a\x58\x8f\x0d\x59\xda\xe4\xe6\x3b\xa2\xac\x3c\xe6\x82\xcc" "\x19\xd4\xe3\x41\x67\x8c\xc3\xa6\x7a\x47\xc1\x13\xb4\xdb\x89\x0f" "\x30\xa9\x2a\xa0\x8a\x1f\x6d\xc8\xfb\x64\x63\xf8\x03\x8c\x2b\x40" "\xb2\x53\x00\x77\xb2\x36\xce\x88\xaf\xcc\xcd\xa0\x8a\xd6\xd7\x5e" "\xee\x18\x99\xb1\x0c\xd8\x00\xc2\xce\x53\x72\xbf\xf2\x2e\xe3\xa3" "\x39\xd4\xb9\xc1\xa2\xf5\xf4\xb8\x20\xf6\x87\xe5\x51\x9b\xd0\x5b" "\x1f\xc5\xda\x0e\xb4\x53\x36\x81\x4f\x48\x13\x2c\x64\x0e\x66\xc3" "\xa0\x2a\x22\xe6\x35\x98\xf9\x4f\x22\xf3\x51\x84\x11\x04\x46\xb6" "\x48\xcf\x84\x74\xf3\x0c\x43\xea\xd5\x83\x09\xfb\x25\x90\x16\x09" "\xe2\x41\x87\xe8\x01\xc8\x09\x56\x1a\x64\x80\x94\x50\xe6\x03\xc4" "\xa8\x03\x95\x25\xc4\x76\xb5\x8e\x32\xce\x2c\x47\xb3\x7d\xa5\x91", 0, 512, }, { GCRY_MD_SHAKE256, "", "\x46\xB9\xDD\x2B\x0B\xA8\x8D\x13\x23\x3B\x3F\xEB\x74\x3E\xEB\x24" "\x3F\xCD\x52\xEA\x62\xB8\x1B\x82\xB5\x0C\x27\x64\x6E\xD5\x76\x2F" "\xD7\x5D\xC4\xDD\xD8\xC0\xF2\x00\xCB\x05\x01\x9D\x67\xB5\x92\xF6" "\xFC\x82\x1C\x49\x47\x9A\xB4\x86\x40\x29\x2E\xAC\xB3\xB7\xC4\xBE" "\x14\x1E\x96\x61\x6F\xB1\x39\x57\x69\x2C\xC7\xED\xD0\xB4\x5A\xE3" "\xDC\x07\x22\x3C\x8E\x92\x93\x7B\xEF\x84\xBC\x0E\xAB\x86\x28\x53" "\x34\x9E\xC7\x55\x46\xF5\x8F\xB7\xC2\x77\x5C\x38\x46\x2C\x50\x10" "\xD8\x46\xC1\x85\xC1\x51\x11\xE5\x95\x52\x2A\x6B\xCD\x16\xCF\x86" "\xF3\xD1\x22\x10\x9E\x3B\x1F\xDD\x94\x3B\x6A\xEC\x46\x8A\x2D\x62" "\x1A\x7C\x06\xC6\xA9\x57\xC6\x2B\x54\xDA\xFC\x3B\xE8\x75\x67\xD6" "\x77\x23\x13\x95\xF6\x14\x72\x93\xB6\x8C\xEA\xB7\xA9\xE0\xC5\x8D" "\x86\x4E\x8E\xFD\xE4\xE1\xB9\xA4\x6C\xBE\x85\x47\x13\x67\x2F\x5C" "\xAA\xAE\x31\x4E\xD9\x08\x3D\xAB\x4B\x09\x9F\x8E\x30\x0F\x01\xB8" "\x65\x0F\x1F\x4B\x1D\x8F\xCF\x3F\x3C\xB5\x3F\xB8\xE9\xEB\x2E\xA2" "\x03\xBD\xC9\x70\xF5\x0A\xE5\x54\x28\xA9\x1F\x7F\x53\xAC\x26\x6B" "\x28\x41\x9C\x37\x78\xA1\x5F\xD2\x48\xD3\x39\xED\xE7\x85\xFB\x7F" "\x5A\x1A\xAA\x96\xD3\x13\xEA\xCC\x89\x09\x36\xC1\x73\xCD\xCD\x0F" "\xAB\x88\x2C\x45\x75\x5F\xEB\x3A\xED\x96\xD4\x77\xFF\x96\x39\x0B" "\xF9\xA6\x6D\x13\x68\xB2\x08\xE2\x1F\x7C\x10\xD0\x4A\x3D\xBD\x4E" "\x36\x06\x33\xE5\xDB\x4B\x60\x26\x01\xC1\x4C\xEA\x73\x7D\xB3\xDC" "\xF7\x22\x63\x2C\xC7\x78\x51\xCB\xDD\xE2\xAA\xF0\xA3\x3A\x07\xB3" "\x73\x44\x5D\xF4\x90\xCC\x8F\xC1\xE4\x16\x0F\xF1\x18\x37\x8F\x11" "\xF0\x47\x7D\xE0\x55\xA8\x1A\x9E\xDA\x57\xA4\xA2\xCF\xB0\xC8\x39" "\x29\xD3\x10\x91\x2F\x72\x9E\xC6\xCF\xA3\x6C\x6A\xC6\xA7\x58\x37" "\x14\x30\x45\xD7\x91\xCC\x85\xEF\xF5\xB2\x19\x32\xF2\x38\x61\xBC" "\xF2\x3A\x52\xB5\xDA\x67\xEA\xF7\xBA\xAE\x0F\x5F\xB1\x36\x9D\xB7" "\x8F\x3A\xC4\x5F\x8C\x4A\xC5\x67\x1D\x85\x73\x5C\xDD\xDB\x09\xD2" "\xB1\xE3\x4A\x1F\xC0\x66\xFF\x4A\x16\x2C\xB2\x63\xD6\x54\x12\x74" "\xAE\x2F\xCC\x86\x5F\x61\x8A\xBE\x27\xC1\x24\xCD\x8B\x07\x4C\xCD" "\x51\x63\x01\xB9\x18\x75\x82\x4D\x09\x95\x8F\x34\x1E\xF2\x74\xBD" "\xAB\x0B\xAE\x31\x63\x39\x89\x43\x04\xE3\x58\x77\xB0\xC2\x8A\x9B" "\x1F\xD1\x66\xC7\x96\xB9\xCC\x25\x8A\x06\x4A\x8F\x57\xE2\x7F\x2A", 0, 512, }, { GCRY_MD_SHAKE256, "\xB3\x2D\x95\xB0\xB9\xAA\xD2\xA8\x81\x6D\xE6\xD0\x6D\x1F\x86\x00" "\x85\x05\xBD\x8C\x14\x12\x4F\x6E\x9A\x16\x3B\x5A\x2A\xDE\x55\xF8" "\x35\xD0\xEC\x38\x80\xEF\x50\x70\x0D\x3B\x25\xE4\x2C\xC0\xAF\x05" "\x0C\xCD\x1B\xE5\xE5\x55\xB2\x30\x87\xE0\x4D\x7B\xF9\x81\x36\x22" "\x78\x0C\x73\x13\xA1\x95\x4F\x87\x40\xB6\xEE\x2D\x3F\x71\xF7\x68" "\xDD\x41\x7F\x52\x04\x82\xBD\x3A\x08\xD4\xF2\x22\xB4\xEE\x9D\xBD" "\x01\x54\x47\xB3\x35\x07\xDD\x50\xF3\xAB\x42\x47\xC5\xDE\x9A\x8A" "\xBD\x62\xA8\xDE\xCE\xA0\x1E\x3B\x87\xC8\xB9\x27\xF5\xB0\x8B\xEB" "\x37\x67\x4C\x6F\x8E\x38\x0C\x04", "\xCC\x2E\xAA\x04\xEE\xF8\x47\x9C\xDA\xE8\x56\x6E\xB8\xFF\xA1\x10" "\x0A\x40\x79\x95\xBF\x99\x9A\xE9\x7E\xDE\x52\x66\x81\xDC\x34\x90" "\x61\x6F\x28\x44\x2D\x20\xDA\x92\x12\x4C\xE0\x81\x58\x8B\x81\x49" "\x1A\xED\xF6\x5C\xAA\xF0\xD2\x7E\x82\xA4\xB0\xE1\xD1\xCA\xB2\x38" "\x33\x32\x8F\x1B\x8D\xA4\x30\xC8\xA0\x87\x66\xA8\x63\x70\xFA\x84" "\x8A\x79\xB5\x99\x8D\xB3\xCF\xFD\x05\x7B\x96\xE1\xE2\xEE\x0E\xF2" "\x29\xEC\xA1\x33\xC1\x55\x48\xF9\x83\x99\x02\x04\x37\x30\xE4\x4B" "\xC5\x2C\x39\xFA\xDC\x1D\xDE\xEA\xD9\x5F\x99\x39\xF2\x20\xCA\x30" "\x06\x61\x54\x0D\xF7\xED\xD9\xAF\x37\x8A\x5D\x4A\x19\xB2\xB9\x3E" "\x6C\x78\xF4\x9C\x35\x33\x43\xA0\xB5\xF1\x19\x13\x2B\x53\x12\xD0" "\x04\x83\x1D\x01\x76\x9A\x31\x6D\x2F\x51\xBF\x64\xCC\xB2\x0A\x21" "\xC2\xCF\x7A\xC8\xFB\x6F\x6E\x90\x70\x61\x26\xBD\xAE\x06\x11\xDD" "\x13\x96\x2E\x8B\x53\xD6\xEA\xE2\x6C\x7B\x0D\x25\x51\xDA\xF6\x24" "\x8E\x9D\x65\x81\x73\x82\xB0\x4D\x23\x39\x2D\x10\x8E\x4D\x34\x43" "\xDE\x5A\xDC\x72\x73\xC7\x21\xA8\xF8\x32\x0E\xCF\xE8\x17\x7A\xC0" "\x67\xCA\x8A\x50\x16\x9A\x6E\x73\x00\x0E\xBC\xDC\x1E\x4E\xE6\x33" "\x9F\xC8\x67\xC3\xD7\xAE\xAB\x84\x14\x63\x98\xD7\xBA\xDE\x12\x1D" "\x19\x89\xFA\x45\x73\x35\x56\x4E\x97\x57\x70\xA3\xA0\x02\x59\xCA" "\x08\x70\x61\x08\x26\x1A\xA2\xD3\x4D\xE0\x0F\x8C\xAC\x7D\x45\xD3" "\x5E\x5A\xA6\x3E\xA6\x9E\x1D\x1A\x2F\x7D\xAB\x39\x00\xD5\x1E\x0B" "\xC6\x53\x48\xA2\x55\x54\x00\x70\x39\xA5\x2C\x3C\x30\x99\x80\xD1" "\x7C\xAD\x20\xF1\x15\x63\x10\xA3\x9C\xD3\x93\x76\x0C\xFE\x58\xF6" "\xF8\xAD\xE4\x21\x31\x28\x82\x80\xA3\x5E\x1D\xB8\x70\x81\x83\xB9" "\x1C\xFA\xF5\x82\x7E\x96\xB0\xF7\x74\xC4\x50\x93\xB4\x17\xAF\xF9" "\xDD\x64\x17\xE5\x99\x64\xA0\x1B\xD2\xA6\x12\xFF\xCF\xBA\x18\xA0" "\xF1\x93\xDB\x29\x7B\x9A\x6C\xC1\xD2\x70\xD9\x7A\xAE\x8F\x8A\x3A" "\x6B\x26\x69\x5A\xB6\x64\x31\xC2\x02\xE1\x39\xD6\x3D\xD3\xA2\x47" "\x78\x67\x6C\xEF\xE3\xE2\x1B\x02\xEC\x4E\x8F\x5C\xFD\x66\x58\x7A" "\x12\xB4\x40\x78\xFC\xD3\x9E\xEE\x44\xBB\xEF\x4A\x94\x9A\x63\xC0" "\xDF\xD5\x8C\xF2\xFB\x2C\xD5\xF0\x02\xE2\xB0\x21\x92\x66\xCF\xC0" "\x31\x81\x74\x86\xDE\x70\xB4\x28\x5A\x8A\x70\xF3\xD3\x8A\x61\xD3" "\x15\x5D\x99\xAA\xF4\xC2\x53\x90\xD7\x36\x45\xAB\x3E\x8D\x80\xF0", 136, 512, }, { GCRY_MD_SHAKE256, "!", "\x35\x78\xa7\xa4\xca\x91\x37\x56\x9c\xdf\x76\xed\x61\x7d\x31\xbb" "\x99\x4f\xca\x9c\x1b\xbf\x8b\x18\x40\x13\xde\x82\x34\xdf\xd1\x3a" "\x3f\xd1\x24\xd4\xdf\x76\xc0\xa5\x39\xee\x7d\xd2\xf6\xe1\xec\x34" "\x61\x24\xc8\x15\xd9\x41\x0e\x14\x5e\xb5\x61\xbc\xd9\x7b\x18\xab" "\x6c\xe8\xd5\x55\x3e\x0e\xab\x3d\x1f\x7d\xfb\x8f\x9d\xee\xfe\x16" "\x84\x7e\x21\x92\xf6\xf6\x1f\xb8\x2f\xb9\x0d\xde\x60\xb1\x90\x63" "\xc5\x6a\x4c\x55\xcd\xd7\xb6\x72\xb7\x5b\xf5\x15\xad\xbf\xe2\x04" "\x90\x3c\x8c\x00\x36\xde\x54\xa2\x99\x9a\x92\x0d\xe9\x0f\x66\xd7" "\xff\x6e\xc8\xe4\xc9\x3d\x24\xae\x34\x6f\xdc\xb3\xa5\xa5\xbd\x57" "\x39\xec\x15\xa6\xed\xdb\x5c\xe5\xb0\x2d\xa5\x30\x39\xfa\xc6\x3e" "\x19\x55\x5f\xaa\x2e\xdd\xc6\x93\xb1\xf0\xc2\xa6\xfc\xbe\x7c\x0a" "\x0a\x09\x1d\x0e\xe7\x00\xd7\x32\x2e\x4b\x0f\xf0\x95\x90\xde\x16" "\x64\x22\xf9\xea\xd5\xda\x4c\x99\x3d\x60\x5f\xe4\xd9\xc6\x34\x84" "\x3a\xa1\x78\xb1\x76\x72\xc6\x56\x8c\x8a\x2e\x62\xab\xeb\xea\x2c" "\x21\xc3\x02\xbd\x36\x6a\xd6\x98\x95\x9e\x1f\x6e\x43\x4a\xf1\x55" "\x56\x8b\x27\x34\xd8\x37\x9f\xcd\x3f\xfe\x64\x89\xba\xff\xa6\xd7" "\x11\x09\x44\x2e\x1b\x34\x4f\x13\x8a\x09\xca\xe3\xe2\xd3\x94\x2e" "\xee\x82\x8f\xc4\x7e\x64\xde\xb5\xe0\x0a\x02\x4a\xe1\xf2\xc0\x77" "\xe6\xb7\xb1\x33\xf6\xc1\xde\x91\x30\x92\xd4\xe8\x29\xec\xd2\xb2" "\xef\x28\xca\x80\x20\x82\x1e\x2b\x8b\xe5\x17\xd9\x3e\xd0\x88\x36" "\xf6\xf0\x66\xcc\x3d\x03\xb6\x25\xd8\x49\x7f\x29\xdb\xc1\xc3\x9e" "\x6f\xe4\x63\x22\x6f\x85\xc1\x28\xa2\xc2\x98\x88\x11\x2e\x06\xa9" "\x9c\x5d\x17\xb2\x5e\x90\x0d\x20\x4f\x39\x72\x31\xcd\xf7\x9c\x31" "\x34\x46\x53\x2d\xad\x07\xf4\xc0\xbd\x9f\xba\x1d\xd4\x13\xd8\xa7" "\xe6\xcb\xc0\xa0\x86\x2c\xc7\x69\x23\x9a\x89\xf9\xdb\x08\x5b\x78" "\xa0\x54\x59\x6a\xd7\x08\x0d\xdf\x96\x01\x9b\x73\x99\xb5\x03\x48" "\x0e\x5a\x65\xa2\x20\x8d\x74\x72\x4c\x98\x7d\x32\x5e\x9b\x0e\x82" "\xfe\xcd\x4f\x27\xf3\x13\x5b\x1d\x9e\x27\xb4\x8e\x69\xdd\x6f\x59" "\x62\xb8\xa6\x3b\x48\x92\x1e\xc8\xee\x53\x86\x9f\x1a\xc1\xc8\x18" "\x23\x87\xee\x0d\x6c\xfe\xf6\x53\xff\x8b\xf6\x05\xf1\x47\x04\xb7" "\x1b\xeb\x65\x53\xf2\x81\xfa\x75\x69\x48\xc4\x38\x49\x4b\x19\xb4" "\xee\x69\xa5\x43\x6b\x22\x2b\xc9\x88\xed\xa4\xac\x60\x00\x24\xc9", 0, 512, }, { GCRY_MD_BLAKE2B_512, "abc", "\xBA\x80\xA5\x3F\x98\x1C\x4D\x0D\x6A\x27\x97\xB6\x9F\x12\xF6\xE9" "\x4C\x21\x2F\x14\x68\x5A\xC4\xB7\x4B\x12\xBB\x6F\xDB\xFF\xA2\xD1" "\x7D\x87\xC5\x39\x2A\xAB\x79\x2D\xC2\x52\xD5\xDE\x45\x33\xCC\x95" "\x18\xD3\x8A\xA8\xDB\xF1\x92\x5A\xB9\x23\x86\xED\xD4\x00\x99\x23" }, { GCRY_MD_BLAKE2B_512, "\x00", "\x96\x1f\x6d\xd1\xe4\xdd\x30\xf6\x39\x01\x69\x0c\x51\x2e\x78\xe4" "\xb4\x5e\x47\x42\xed\x19\x7c\x3c\x5e\x45\xc5\x49\xfd\x25\xf2\xe4" "\x18\x7b\x0b\xc9\xfe\x30\x49\x2b\x16\xb0\xd0\xbc\x4e\xf9\xb0\xf3" "\x4c\x70\x03\xfa\xc0\x9a\x5e\xf1\x53\x2e\x69\x43\x02\x34\xce\xbd", 1, 64, "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f" "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f" "\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f" "\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f", 64 }, #include "./blake2b.h" { GCRY_MD_BLAKE2B_160, "", "\xad\x75\xea\xd7\x9f\x71\x21\xd1\xf0\x8a\xfe\x59\x99\x27\xa5\xa3" "\x8b\xe1\xb1\x79", 0, 20, "\x65\x65\xcb\x30\xfb\x2c\x28\x54\x7c\xd0\x4c\x1d\x6a\x88\xf2\x7a" "\x6d\xe8\x55\x3d", 20 }, { GCRY_MD_BLAKE2B_160, "\x9c\x9c\x38", "\x82\x79\x9d\x7b\xe8\xf4\xd1\x69\xfb\x85\xe6\x63\x6a\x7b\x6c\x50" "\xa0\x1f\x70\xa2", 3, 20, "\x65\x65\xcb\x30\xfb\x2c\x28\x54\x7c\xd0\x4c\x1d\x6a\x88\xf2\x7a" "\x6d\xe8\x55\x3d", 20 }, { GCRY_MD_BLAKE2B_256, "", "\x89\x36\x29\x47\x52\x79\xdf\xd8\x2a\x84\x1a\x8f\x21\xa3\x72\xed" "\x30\xcc\xb8\xae\x34\x62\xe1\x90\x7f\x50\x66\x3f\x3c\x03\x66\x83", 0, 32, "\xd5\xd5\xab\x80\x2c\xad\xd9\x86\x60\xe7\x47\x2f\x77\xa6\x1d\xc4" "\xe2\xa6\x88\x2f\xb7\xe6\x9e\x85\x23\xa9\xcd\x76\x43\xb9\xfd\xb7", 32 }, { GCRY_MD_BLAKE2B_256, "\x9c\x9c\x38", "\x01\x6a\x18\xbb\x10\xe0\xc3\xa5\xe5\x9f\xce\xfd\x1a\x40\x7a\xb7" "\xf1\xc0\x36\x1b\x3f\x98\x34\x77\x42\x54\xd3\xf0\x4c\xda\x38\x98", 3, 32, "\xd5\xd5\xab\x80\x2c\xad\xd9\x86\x60\xe7\x47\x2f\x77\xa6\x1d\xc4" "\xe2\xa6\x88\x2f\xb7\xe6\x9e\x85\x23\xa9\xcd\x76\x43\xb9\xfd\xb7", 32 }, { GCRY_MD_BLAKE2B_384, "", "\xd7\x2c\x9b\x4a\x73\x4e\xb2\x07\xe9\xdd\xbf\xf0\x0b\x10\xc3\x70" "\xc8\x9d\x67\xd7\x96\xc3\xa7\xb9\x68\x15\xa9\x53\x92\x1b\xb2\x97" "\x59\xd2\x9d\x25\x63\xf3\xda\x4d\x7f\x3e\xa4\xa6\xe3\x4c\x32\x6b", 0, 48, "\xc0\xc0\x80\x41\xc2\x03\xc6\xca\x90\x5b\xeb\x46\x32\x79\xac\x26" "\xd3\xf9\xcc\xc6\x93\x5a\xed\x48\x35\x7d\xb3\x31\xe5\x16\xfb\x12" "\x0e\x21\x2f\x51\x80\xd1\x52\x24\x77\x9c\x13\xaf\xc3\x73\x37\xaa", 48 }, { GCRY_MD_BLAKE2B_384, "\x9c\x9c\x38", "\xef\x46\xfa\x54\xa2\xc2\x20\xda\x06\xa8\x4c\x77\x6e\x87\xdd\x0a" "\x21\xee\xb5\xe9\x40\x1a\x0a\x78\x11\x19\x74\x18\xfe\x92\x70\x15" "\x77\xd0\xa8\x53\x24\x48\xe8\xb8\x53\x6a\xa6\xc7\x42\xcd\x2c\x62", 3, 48, "\xc0\xc0\x80\x41\xc2\x03\xc6\xca\x90\x5b\xeb\x46\x32\x79\xac\x26" "\xd3\xf9\xcc\xc6\x93\x5a\xed\x48\x35\x7d\xb3\x31\xe5\x16\xfb\x12" "\x0e\x21\x2f\x51\x80\xd1\x52\x24\x77\x9c\x13\xaf\xc3\x73\x37\xaa", 48 }, { GCRY_MD_BLAKE2B_512, "", "\xd7\x4b\xf3\x1e\x5c\xe5\xd8\xa2\x5d\x09\x21\x52\x53\xca\xd2\xf8" "\xd2\xfd\xa9\x10\x09\x30\x16\x05\xa6\x8c\xc3\x86\x5b\xb7\x93\x5b" "\xca\xff\x6f\x2a\xf6\x43\xa7\x76\x99\xe8\x02\x61\xa1\xfd\x2c\x80" "\xe8\x37\xb5\x62\x32\xf7\xb1\x46\x43\x4a\xa7\x4d\x71\x18\xbb\x16", 0, 64, "\xab\xab\x56\x01\x58\x5a\xb3\x0d\xc1\xce\x8f\x5e\xee\x4d\x3b\x88" "\xc4\x4c\x11\x5e\x6f\xcd\x3d\x0a\x47\x52\x9a\xec\x86\x73\xfa\x6e" "\x68\xd6\x3f\x16\x55\x6b\xc1\x2d\xef\x1d\x0c\x29\x35\x5f\x94\xf3" "\x88\x7c\x04\x81\x86\x07\x8e\x95\x23\xb9\xdd\x97\x74\x0c\x80\x8c", 64 }, { GCRY_MD_BLAKE2B_512, "\x9c\x9c\x38", "\x70\xfc\x57\xe1\x49\x5f\xe4\x39\x0d\x38\xa1\xd3\x97\x05\xee\xf6" "\xaa\xbb\xd2\x64\xc7\xce\x66\x11\x8d\x0a\x87\xd4\x25\x94\xb3\x87" "\xdc\x50\x18\x8b\xba\x61\xf0\x91\xd6\xb3\x4f\xf5\x4e\x09\x1e\x70" "\x24\x01\x83\xcd\xb9\x21\x1f\x14\x39\x77\x5c\xc6\xe6\xe9\x35\x73", 3, 64, "\xab\xab\x56\x01\x58\x5a\xb3\x0d\xc1\xce\x8f\x5e\xee\x4d\x3b\x88" "\xc4\x4c\x11\x5e\x6f\xcd\x3d\x0a\x47\x52\x9a\xec\x86\x73\xfa\x6e" "\x68\xd6\x3f\x16\x55\x6b\xc1\x2d\xef\x1d\x0c\x29\x35\x5f\x94\xf3" "\x88\x7c\x04\x81\x86\x07\x8e\x95\x23\xb9\xdd\x97\x74\x0c\x80\x8c", 64 }, { GCRY_MD_BLAKE2B_512, "!", "\x98\xfb\x3e\xfb\x72\x06\xfd\x19\xeb\xf6\x9b\x6f\x31\x2c\xf7\xb6" "\x4e\x3b\x94\xdb\xe1\xa1\x71\x07\x91\x39\x75\xa7\x93\xf1\x77\xe1" "\xd0\x77\x60\x9d\x7f\xba\x36\x3c\xbb\xa0\x0d\x05\xf7\xaa\x4e\x4f" "\xa8\x71\x5d\x64\x28\x10\x4c\x0a\x75\x64\x3b\x0f\xf3\xfd\x3e\xaf" }, { GCRY_MD_BLAKE2B_512, "?", "\xae\x9c\xf5\x7a\xc2\xff\x7b\x37\x7a\x5b\xb5\xcc\x2e\x62\x92\x20" "\xa9\xba\x0a\x09\xc2\x2a\x0f\xdb\xd9\xa3\xae\xd6\x32\xc1\x72\x0e" "\x6d\x82\x9f\x74\x7f\xba\x12\xe8\x31\xa2\x45\x8d\xf0\x73\x4e\xe0" "\x12\x27\x52\xd3\xe2\x2c\x36\xc4\x42\x89\x3b\xcd\xd1\xbd\xd9\x08" }, { GCRY_MD_BLAKE2B_384, "?", "\x22\x66\x8e\x05\x81\x44\x52\xa5\x23\x84\xce\x67\xd4\xad\x0e\x03" "\xdf\xe7\x1a\xc1\x56\x9d\x95\x4a\xd2\x22\x7a\x70\x2a\xfe\x6c\x68" "\x5c\x7d\x65\x30\x2b\xc0\xde\xc6\xea\x72\x1e\xdd\x46\xdf\xb2\x08" }, { GCRY_MD_BLAKE2B_256, "?", "\xfa\x11\x30\xd8\xba\x8a\x4c\x5a\x0e\x6f\x4f\x4c\xd2\xd1\x38\x0c" "\xb9\x22\x2a\xbd\xf6\x20\x70\xf8\x02\x1b\x34\xdd\xd7\x24\x92\x1b" }, { GCRY_MD_BLAKE2B_160, "?", "\xe7\x86\x08\x31\xf8\x96\x8d\x64\x9b\xe0\x15\x68\x33\xf3\xbd\x2a" "\x5f\x0b\xdb\x40" }, { GCRY_MD_BLAKE2S_256, "abc", "\x50\x8C\x5E\x8C\x32\x7C\x14\xE2\xE1\xA7\x2B\xA3\x4E\xEB\x45\x2F" "\x37\x45\x8B\x20\x9E\xD6\x3A\x29\x4D\x99\x9B\x4C\x86\x67\x59\x82" }, #include "./blake2s.h" { GCRY_MD_BLAKE2S_128, "", "\x84\x89\x68\xb3\x59\x01\xe9\x57\x9a\x4d\xbf\x28\xdf\x99\xec\x23", 0, 16, "\xea\xea\xd5\xc0\x96\x56\xec\x43\x30\x73\xa3\x17\xbb\xd3\x8e\x62", 16 }, { GCRY_MD_BLAKE2S_128, "\x9c\x9c\x38", "\x2e\xbb\x18\x78\xda\x34\x05\xad\x98\x1a\x33\x06\x50\x35\xd3\x75", 3, 16, "\xea\xea\xd5\xc0\x96\x56\xec\x43\x30\x73\xa3\x17\xbb\xd3\x8e\x62", 16 }, { GCRY_MD_BLAKE2S_128, "\xab\xab\x56\x01\x58\x5a\xb3\x0d\xc1\xce\x8f\x5e\xee\x4d\x3b\x88" "\xc4\x4c\x11\x5e\x6f\xcd\x3d\x0a\x47\x52\x9a\xec\x86\x73\xfa\x6e" "\x68\xd6\x3f\x16\x55\x6b\xc1\x2d\xef\x1d\x0c\x29\x35\x5f\x94\xf3" "\x88\x7c\x04\x81\x86\x07\x8e\x95\x23\xb9\xdd\x97\x74\x0c\x80\x8c", "\x3c\xd4\xea\xd7\x88\x0b\x8e\x82\xde\x07\x9c\x1f\xad\x34\x17\xd4", 64, 16, "\xea\xea\xd5\xc0\x96\x56\xec\x43\x30\x73\xa3\x17\xbb\xd3\x8e\x62", 16 }, { GCRY_MD_BLAKE2S_128, "\x8a\x8a\x14\x9e\xb2\x50\x02\x52\x54\xa6\xfa\xa0\x9a\x3a\xd4\x0e" "\xe3\xf2\xd5\xc7\x9d\x64\x02\x66\x68\xcf\x38\x08\x41\x49\x8a\xd3" "\x5e\x32\x90\xc2\x53\x15\x68\x7e\xe6\x65\x4b\xb0\xfc\xad\xaa\x58" "\x02\x5b\x5e\xb9\x18\xd1\xe9\xbb\xa5\x61\x07\x68\x70\xd9\x49\x22" "\x6b", "\xee\x92\xc5\x25\x4c\x29\x7a\x88\xe6\x9a\x23\x69\x56\xb6\x7c\xee", 65, 16, "\xea\xea\xd5\xc0\x96\x56\xec\x43\x30\x73\xa3\x17\xbb\xd3\x8e\x62", 16 }, { GCRY_MD_BLAKE2S_160, "", "\x68\x64\x48\x80\x0c\x80\xc6\xd0\x4f\xb7\x3f\xc1\x7f\xa0\x8c\xa2" "\x39\x03\xe1\xe9", 0, 20, "\x65\x65\xcb\x30\xfb\x2c\x28\x54\x7c\xd0\x4c\x1d\x6a\x88\xf2\x7a" "\x6d\xe8\x55\x3d", 20 }, { GCRY_MD_BLAKE2S_160, "\x9c\x9c\x38", "\xba\xb3\x5b\x8c\x87\x04\x1a\x00\x24\x44\xa5\xca\x45\x13\x2d\x75" "\xef\xd3\x4c\xb9", 3, 20, "\x65\x65\xcb\x30\xfb\x2c\x28\x54\x7c\xd0\x4c\x1d\x6a\x88\xf2\x7a" "\x6d\xe8\x55\x3d", 20 }, { GCRY_MD_BLAKE2S_160, "\xab\xab\x56\x01\x58\x5a\xb3\x0d\xc1\xce\x8f\x5e\xee\x4d\x3b\x88" "\xc4\x4c\x11\x5e\x6f\xcd\x3d\x0a\x47\x52\x9a\xec\x86\x73\xfa\x6e" "\x68\xd6\x3f\x16\x55\x6b\xc1\x2d\xef\x1d\x0c\x29\x35\x5f\x94\xf3" "\x88\x7c\x04\x81\x86\x07\x8e\x95\x23\xb9\xdd\x97\x74\x0c\x80\x8c", "\xe8\xc3\xf1\xdb\x1c\xf8\xe9\xd1\xb5\x4a\x54\x0a\xdc\xe7\x18\x13" "\x0f\xf4\x12\x98", 64, 20, "\x65\x65\xcb\x30\xfb\x2c\x28\x54\x7c\xd0\x4c\x1d\x6a\x88\xf2\x7a" "\x6d\xe8\x55\x3d", 20 }, { GCRY_MD_BLAKE2S_160, "\x8a\x8a\x14\x9e\xb2\x50\x02\x52\x54\xa6\xfa\xa0\x9a\x3a\xd4\x0e" "\xe3\xf2\xd5\xc7\x9d\x64\x02\x66\x68\xcf\x38\x08\x41\x49\x8a\xd3" "\x5e\x32\x90\xc2\x53\x15\x68\x7e\xe6\x65\x4b\xb0\xfc\xad\xaa\x58" "\x02\x5b\x5e\xb9\x18\xd1\xe9\xbb\xa5\x61\x07\x68\x70\xd9\x49\x22" "\x6b", "\x59\x02\xf8\x38\x18\x77\x9c\xd8\x13\x40\x0f\xd6\xbb\x23\x04\x1b" "\x64\x9a\x57\xa7", 65, 20, "\x65\x65\xcb\x30\xfb\x2c\x28\x54\x7c\xd0\x4c\x1d\x6a\x88\xf2\x7a" "\x6d\xe8\x55\x3d", 20 }, { GCRY_MD_BLAKE2S_224, "", "\xa8\x66\x86\x63\x35\x3a\xe0\x8f\x4e\x4b\x6b\x1e\xcb\x43\x19\xc8" "\x2b\x41\x3f\x5e\xe5\x43\x95\x9c\xa5\x9a\x73\x1b", 0, 28, "\x5a\x5a\xb5\x10\xc6\xd7\x9e\x76\x14\x8a\x9e\x29\xc8\xf1\xba\xab" "\x65\x11\x77\x89\x00\x89\x8a\x14\x9f\xb4\x53\x07", 28 }, { GCRY_MD_BLAKE2S_224, "\x9c\x9c\x38", "\x1a\x34\x9d\xc1\x51\xbd\x8b\xa2\xa7\xa6\x6b\xe4\x93\x98\x51\x88" "\x33\x49\x71\x02\x09\xb1\x20\x85\x8c\x4c\x67\xb8", 3, 28, "\x5a\x5a\xb5\x10\xc6\xd7\x9e\x76\x14\x8a\x9e\x29\xc8\xf1\xba\xab" "\x65\x11\x77\x89\x00\x89\x8a\x14\x9f\xb4\x53\x07", 28 }, { GCRY_MD_BLAKE2S_224, "\xab\xab\x56\x01\x58\x5a\xb3\x0d\xc1\xce\x8f\x5e\xee\x4d\x3b\x88" "\xc4\x4c\x11\x5e\x6f\xcd\x3d\x0a\x47\x52\x9a\xec\x86\x73\xfa\x6e" "\x68\xd6\x3f\x16\x55\x6b\xc1\x2d\xef\x1d\x0c\x29\x35\x5f\x94\xf3" "\x88\x7c\x04\x81\x86\x07\x8e\x95\x23\xb9\xdd\x97\x74\x0c\x80\x8c", "\x3a\x0e\xd5\x46\x95\x8c\xd6\xf9\x7c\x38\xd0\xe7\x1c\xfd\xd4\xc5" "\x67\x6d\x5c\xcc\x35\x06\xec\x87\x87\x09\x26\x39", 64, 28, "\x5a\x5a\xb5\x10\xc6\xd7\x9e\x76\x14\x8a\x9e\x29\xc8\xf1\xba\xab" "\x65\x11\x77\x89\x00\x89\x8a\x14\x9f\xb4\x53\x07", 28 }, { GCRY_MD_BLAKE2S_224, "\x8a\x8a\x14\x9e\xb2\x50\x02\x52\x54\xa6\xfa\xa0\x9a\x3a\xd4\x0e" "\xe3\xf2\xd5\xc7\x9d\x64\x02\x66\x68\xcf\x38\x08\x41\x49\x8a\xd3" "\x5e\x32\x90\xc2\x53\x15\x68\x7e\xe6\x65\x4b\xb0\xfc\xad\xaa\x58" "\x02\x5b\x5e\xb9\x18\xd1\xe9\xbb\xa5\x61\x07\x68\x70\xd9\x49\x22" "\x6b", "\x63\xd7\x98\xcc\x8e\xe3\x00\x45\x2f\xd8\x19\x83\x02\x94\x7f\xf1" "\xb3\x82\x73\xaa\x19\xae\x72\x8b\x1f\x64\xbe\x88", 65, 28, "\x5a\x5a\xb5\x10\xc6\xd7\x9e\x76\x14\x8a\x9e\x29\xc8\xf1\xba\xab" "\x65\x11\x77\x89\x00\x89\x8a\x14\x9f\xb4\x53\x07", 28 }, { GCRY_MD_BLAKE2S_256, "", "\x98\xf3\x21\xe5\x43\xb8\x07\x35\x27\x9c\x86\x1c\x36\x33\x9b\x43" "\x45\x50\xc6\x9d\x23\xc6\xc8\xff\x96\xbf\x4e\x03\x86\x10\x24\xfd", 0, 32, "\xd5\xd5\xab\x80\x2c\xad\xd9\x86\x60\xe7\x47\x2f\x77\xa6\x1d\xc4" "\xe2\xa6\x88\x2f\xb7\xe6\x9e\x85\x23\xa9\xcd\x76\x43\xb9\xfd\xb7", 32 }, { GCRY_MD_BLAKE2S_256, "\x9c\x9c\x38", "\x7b\x10\xa3\x67\xb8\x5d\x29\x9a\x91\x27\x37\x05\x9d\x05\x9d\x3d" "\xe6\x42\xa3\x19\x04\x57\x01\xb6\x25\x0b\xfd\x3c\x6c\xb9\x4f\x87", 3, 32, "\xd5\xd5\xab\x80\x2c\xad\xd9\x86\x60\xe7\x47\x2f\x77\xa6\x1d\xc4" "\xe2\xa6\x88\x2f\xb7\xe6\x9e\x85\x23\xa9\xcd\x76\x43\xb9\xfd\xb7", 32 }, { GCRY_MD_BLAKE2S_256, "\xab\xab\x56\x01\x58\x5a\xb3\x0d\xc1\xce\x8f\x5e\xee\x4d\x3b\x88" "\xc4\x4c\x11\x5e\x6f\xcd\x3d\x0a\x47\x52\x9a\xec\x86\x73\xfa\x6e" "\x68\xd6\x3f\x16\x55\x6b\xc1\x2d\xef\x1d\x0c\x29\x35\x5f\x94\xf3" "\x88\x7c\x04\x81\x86\x07\x8e\x95\x23\xb9\xdd\x97\x74\x0c\x80\x8c", "\xd7\x8b\x98\x28\x54\x4c\xc1\x62\x9e\xab\x7d\xfe\xb1\xfa\xdd\x2b" "\xed\x98\x1c\xe6\x5f\xef\xd8\x08\x42\x9a\x11\x1e\x97\x44\x92\xa3", 64, 32, "\xd5\xd5\xab\x80\x2c\xad\xd9\x86\x60\xe7\x47\x2f\x77\xa6\x1d\xc4" "\xe2\xa6\x88\x2f\xb7\xe6\x9e\x85\x23\xa9\xcd\x76\x43\xb9\xfd\xb7", 32 }, { GCRY_MD_BLAKE2S_256, "\x8a\x8a\x14\x9e\xb2\x50\x02\x52\x54\xa6\xfa\xa0\x9a\x3a\xd4\x0e" "\xe3\xf2\xd5\xc7\x9d\x64\x02\x66\x68\xcf\x38\x08\x41\x49\x8a\xd3" "\x5e\x32\x90\xc2\x53\x15\x68\x7e\xe6\x65\x4b\xb0\xfc\xad\xaa\x58" "\x02\x5b\x5e\xb9\x18\xd1\xe9\xbb\xa5\x61\x07\x68\x70\xd9\x49\x22" "\x6b", "\x1b\x9e\x26\x9a\x90\xf8\x73\x51\x73\xbc\x4f\x65\xce\x29\x2c\x61" "\x16\x65\xc7\xb0\x72\x07\xa8\x0b\xfb\x2e\xea\x12\x7d\x97\xcd\x06", 65, 32, "\xd5\xd5\xab\x80\x2c\xad\xd9\x86\x60\xe7\x47\x2f\x77\xa6\x1d\xc4" "\xe2\xa6\x88\x2f\xb7\xe6\x9e\x85\x23\xa9\xcd\x76\x43\xb9\xfd\xb7", 32 }, { GCRY_MD_BLAKE2S_256, "!", "\xbe\xc0\xc0\xe6\xcd\xe5\xb6\x7a\xcb\x73\xb8\x1f\x79\xa6\x7a\x40" "\x79\xae\x1c\x60\xda\xc9\xd2\x66\x1a\xf1\x8e\x9f\x8b\x50\xdf\xa5" }, { GCRY_MD_BLAKE2S_256, "?", "\xdc\x5a\xe7\x1b\xd4\x63\xa1\xf8\x4d\x73\x33\x44\x63\x6b\xa6\x87" "\xe6\xbd\xf4\xba\xed\xc3\xef\xc8\xb3\x86\x55\xbb\x08\x56\x3e\xdb" }, { GCRY_MD_BLAKE2S_224, "?", "\x2e\x34\x7d\x6b\xcc\x80\xbe\xc3\xf8\x61\x35\x6a\x88\x27\xcd\x84" "\x32\xd4\xd4\x05\xe0\x43\x20\x58\xc7\xb6\xda\xa3" }, { GCRY_MD_BLAKE2S_160, "?", "\xaa\x83\xe1\xcd\x8d\x4e\x9c\xb7\xf4\x6b\x43\xe1\xbc\x6f\x73\x3b" "\x0e\xfc\x29\xde" }, { GCRY_MD_BLAKE2S_128, "?", "\x70\x0b\x8a\x71\x1d\x34\x0a\xf0\x13\x93\x19\x93\x5e\xd7\x54\x9c" }, { 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)) { if (in_fips_mode) { if (verbose) fprintf (stderr, " algorithm %d not available in fips mode\n", algos[i].md); } else show_md_not_available (algos[i].md); continue; } if (!strcmp (algos[i].data, "*")) { if (verbose) fprintf (stderr, " checking %s [%i] for final handling\n", gcry_md_algo_name (algos[i].md), algos[i].md); check_one_md_final (algos[i].md, algos[i].expect, algos[i].expectlen); continue; } if (verbose) fprintf (stderr, " checking %s [%i] for length %d\n", gcry_md_algo_name (algos[i].md), algos[i].md, (!strcmp (algos[i].data, "!") || !strcmp (algos[i].data, "?"))? 1000000 : (int)strlen(algos[i].data)); check_one_md (algos[i].md, algos[i].data, algos[i].datalen > 0 ? algos[i].datalen : strlen (algos[i].data), algos[i].expect, algos[i].expectlen, algos[i].key, algos[i].keylen); if (algos[i].key && algos[i].keylen) continue; check_one_md_multi (algos[i].md, algos[i].data, algos[i].datalen > 0 ? algos[i].datalen : strlen (algos[i].data), algos[i].expect); } /* Check the Whirlpool bug emulation. */ if (!gcry_md_test_algo (GCRY_MD_WHIRLPOOL) && !in_fips_mode) { static const char expect[] = "\x35\x28\xd6\x4c\x56\x2c\x55\x2e\x3b\x91\x93\x95\x7b\xdd\xcc\x6e" "\x6f\xb7\xbf\x76\x22\x9c\xc6\x23\xda\x3e\x09\x9b\x36\xe8\x6d\x76" "\x2f\x94\x3b\x0c\x63\xa0\xba\xa3\x4d\x66\x71\xe6\x5d\x26\x67\x28" "\x36\x1f\x0e\x1a\x40\xf0\xce\x83\x50\x90\x1f\xfa\x3f\xed\x6f\xfd"; gcry_md_hd_t hd; int algo = GCRY_MD_WHIRLPOOL; unsigned char *p; int mdlen; err = gcry_md_open (&hd, GCRY_MD_WHIRLPOOL, GCRY_MD_FLAG_BUGEMU1); if (err) { fail ("algo %d, gcry_md_open failed: %s\n", algo, gpg_strerror (err)); goto leave; } mdlen = gcry_md_get_algo_dlen (algo); if (mdlen < 1 || mdlen > 500) { fail ("algo %d, gcry_md_get_algo_dlen failed: %d\n", algo, mdlen); gcry_md_close (hd); goto leave; } /* Hash 62 byes in chunks. */ gcry_md_write (hd, "1234567890", 10); gcry_md_write (hd, "1234567890123456789012345678901234567890123456789012", 52); p = gcry_md_read (hd, algo); if (memcmp (p, expect, mdlen)) { printf ("computed: "); for (i = 0; i < mdlen; i++) printf ("%02x ", p[i] & 0xFF); printf ("\nexpected: "); for (i = 0; i < mdlen; i++) printf ("%02x ", expect[i] & 0xFF); printf ("\n"); fail ("algo %d, digest mismatch\n", algo); } gcry_md_close (hd); } leave: if (verbose) fprintf (stderr, "Completed hash checks.\n"); } static void check_one_hmac (int algo, const char *data, int datalen, const char *key, int keylen, const char *expect) { gcry_md_hd_t hd, hd2; unsigned char *p; int mdlen; int i; gcry_error_t err = 0; err = gcry_md_open (&hd, algo, GCRY_MD_FLAG_HMAC); if (err) { fail ("algo %d, gcry_md_open failed: %s\n", algo, gpg_strerror (err)); return; } mdlen = gcry_md_get_algo_dlen (algo); if (mdlen < 1 || mdlen > 500) { fail ("algo %d, gcry_md_get_algo_dlen failed: %d\n", algo, mdlen); return; } 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)) { if (in_fips_mode) { if (verbose) fprintf (stderr, " algorithm %d not available in fips mode\n", algos[i].md); } else show_old_hmac_not_available (algos[i].md); continue; } if (verbose) fprintf (stderr, " checking %s [%i] for %d byte key and %d byte data\n", gcry_md_algo_name (algos[i].md), algos[i].md, (int)strlen(algos[i].key), (int)strlen(algos[i].data)); check_one_hmac (algos[i].md, algos[i].data, strlen (algos[i].data), algos[i].key, strlen(algos[i].key), algos[i].expect); } if (verbose) fprintf (stderr, "Completed hashed MAC checks.\n"); } static void check_one_mac (int algo, const char *data, int datalen, const char *key, int keylen, const char *iv, int ivlen, const char *expect, int test_buffering) { gcry_mac_hd_t hd; unsigned char *p; unsigned int maclen; size_t macoutlen; int i; gcry_error_t err = 0; if (test_buffering) { if ((*data == '!' && !data[1]) || (*data == '?' && !data[1])) { return; /* Skip. */ } } err = gcry_mac_open (&hd, algo, 0, NULL); if (err) { fail ("algo %d, gcry_mac_open failed: %s\n", algo, gpg_strerror (err)); return; } i = gcry_mac_get_algo (hd); if (i != algo) { fail ("algo %d, gcry_mac_get_algo failed: %d\n", algo, i); } maclen = gcry_mac_get_algo_maclen (algo); if (maclen < 1 || maclen > 500) { fail ("algo %d, gcry_mac_get_algo_maclen failed: %d\n", algo, maclen); return; } p = malloc(maclen); if (!p) { fail ("algo %d, could not malloc %d bytes\n", algo, maclen); return; } clutter_vector_registers(); err = gcry_mac_setkey (hd, key, keylen); if (err) 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)) { if (in_fips_mode) { if (verbose) fprintf (stderr, " algorithm %d not available in fips mode\n", algos[i].algo); } else show_mac_not_available (algos[i].algo); continue; } if (verbose) fprintf (stderr, " checking %s [%i] for %d byte key and %d byte data\n", gcry_mac_algo_name (algos[i].algo), algos[i].algo, (int)strlen(algos[i].key), (!strcmp(algos[i].data, "!") || !strcmp(algos[i].data, "?")) ? 1000000 : (int)strlen(algos[i].data)); klen = algos[i].klen ? algos[i].klen : strlen(algos[i].key); dlen = algos[i].dlen ? algos[i].dlen : strlen (algos[i].data); check_one_mac (algos[i].algo, algos[i].data, dlen, algos[i].key, klen, algos[i].iv, algos[i].iv ? strlen(algos[i].iv) : 0, algos[i].expect, 0); check_one_mac (algos[i].algo, algos[i].data, dlen, algos[i].key, klen, algos[i].iv, algos[i].iv ? strlen(algos[i].iv) : 0, algos[i].expect, 1); } if (verbose) fprintf (stderr, "Completed MAC checks.\n"); } /* Check that the signature SIG matches the hash HASH. PKEY is the public key used for the verification. BADHASH is a hash value which should result in a bad signature status. */ static void verify_one_signature (gcry_sexp_t pkey, gcry_sexp_t hash, gcry_sexp_t badhash, gcry_sexp_t sig) { gcry_error_t rc; rc = gcry_pk_verify (sig, hash, pkey); if (rc) fail ("gcry_pk_verify failed: %s\n", gpg_strerror (rc)); rc = gcry_pk_verify (sig, badhash, pkey); if (gcry_err_code (rc) != GPG_ERR_BAD_SIGNATURE) fail ("gcry_pk_verify failed to detect a bad signature: %s\n", gpg_strerror (rc)); } /* Test the public key sign function using the private key SKEY. PKEY is used for verification. */ static void check_pubkey_sign (int n, gcry_sexp_t skey, gcry_sexp_t pkey, int algo) { gcry_error_t rc; gcry_sexp_t sig, badhash, hash; int dataidx; static const char baddata[] = "(data\n (flags pkcs1)\n" " (hash sha1 #11223344556677889900AABBCCDDEEFF10203041#))\n"; static const struct { const char *data; int algo; int expected_rc; } datas[] = { { "(data\n (flags pkcs1)\n" " (hash sha1 #11223344556677889900AABBCCDDEEFF10203040#))\n", GCRY_PK_RSA, 0 }, { "(data\n (flags pkcs1-raw)\n" " (hash sha1 #11223344556677889900AABBCCDDEEFF10203040#))\n", GCRY_PK_RSA, GPG_ERR_CONFLICT }, { "(data\n (flags oaep)\n" " (hash sha1 #11223344556677889900AABBCCDDEEFF10203040#))\n", 0, GPG_ERR_CONFLICT }, /* This test is to see whether hash algorithms not hard wired in pubkey.c are detected: */ { "(data\n (flags pkcs1)\n" " (hash oid.1.3.14.3.2.29 " " #11223344556677889900AABBCCDDEEFF10203040#))\n", GCRY_PK_RSA, 0 }, { "(data\n (flags )\n" " (hash sha1 #11223344556677889900AABBCCDDEEFF10203040#))\n", 0, GPG_ERR_CONFLICT }, { "(data\n (flags pkcs1)\n" " (hash foo #11223344556677889900AABBCCDDEEFF10203040#))\n", GCRY_PK_RSA, GPG_ERR_DIGEST_ALGO }, { "(data\n (flags )\n" " (value #11223344556677889900AA#))\n", 0, 0 }, { "(data\n (flags )\n" " (value #0090223344556677889900AA#))\n", 0, 0 }, { "(data\n (flags raw)\n" " (value #11223344556677889900AA#))\n", 0, 0 }, { "(data\n (flags pkcs1)\n" " (value #11223344556677889900AA#))\n", GCRY_PK_RSA, GPG_ERR_CONFLICT }, { "(data\n (flags pkcs1-raw)\n" " (value #11223344556677889900AA#))\n", GCRY_PK_RSA, 0 }, { "(data\n (flags raw foo)\n" " (value #11223344556677889900AA#))\n", 0, GPG_ERR_INV_FLAG }, { "(data\n (flags pss)\n" " (hash sha1 #11223344556677889900AABBCCDDEEFF10203040#))\n", GCRY_PK_RSA, 0 }, { "(data\n (flags pss)\n" " (hash sha1 #11223344556677889900AABBCCDDEEFF10203040#)\n" " (random-override #4253647587980912233445566778899019283747#))\n", GCRY_PK_RSA, 0 }, { "(data\n (flags pss)\n" " (hash-algo sha1)\n" " (value #11223344556677889900AA#))\n", GCRY_PK_RSA, 0 }, { "(data\n (flags pss)\n" " (hash-algo sha1)\n" " (value #11223344556677889900AA#)\n" " (random-override #4253647587980912233445566778899019283747#))\n", GCRY_PK_RSA, 0 }, { NULL } }; rc = gcry_sexp_sscan (&badhash, NULL, baddata, strlen (baddata)); if (rc) die ("converting data failed: %s\n", gpg_strerror (rc)); 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. */ gcry_control (GCRYCTL_FORCE_FIPS_MODE, 0); if (!gcry_control (GCRYCTL_OPERATIONAL_P, 0)) fail ("not in operational state after self-test\n"); /* Get us into the error state. */ err = gcry_md_open (&md, GCRY_MD_SHA1, 0); if (err) fail ("failed to open SHA-1 hash context: %s\n", gpg_strerror (err)); else { err = gcry_md_enable (md, GCRY_MD_SHA256); if (err) fail ("failed to add SHA-256 hash context: %s\n", gpg_strerror (err)); else { /* gcry_md_get_algo is only defined for a context with just one digest algorithm. With our setup it should put the oibrary intoerror state. */ fputs ("Note: Two lines with error messages follow " "- this is expected\n", stderr); gcry_md_get_algo (md); gcry_md_close (md); if (gcry_control (GCRYCTL_OPERATIONAL_P, 0)) fail ("expected error state but still in operational state\n"); else { /* Now run a self-test and to get back into operational state. */ gcry_control (GCRYCTL_FORCE_FIPS_MODE, 0); if (!gcry_control (GCRYCTL_OPERATIONAL_P, 0)) fail ("did not reach operational after error " "and self-test\n"); } } } } else { /* If in standard mode, run selftests. */ if (gcry_control (GCRYCTL_SELFTEST, 0)) fail ("running self-test failed\n"); } if (verbose) fprintf (stderr, "\nAll tests completed. Errors: %i\n", error_count); if (in_fips_mode && !gcry_fips_mode_active ()) fprintf (stderr, "FIPS mode is not anymore active\n"); return error_count ? 1 : 0; }