From jan.bilek at eftlab.co.uk Mon Dec 1 09:34:08 2014 From: jan.bilek at eftlab.co.uk (Jan Bilek) Date: Mon, 01 Dec 2014 18:34:08 +1000 Subject: AES128 in CBC mode decode on longer data [libgcrypt] In-Reply-To: <547B1932.30701@eftlab.co.uk> References: <5477CB7C.6020507@eftlab.co.uk> <547ADE44.2020907@iki.fi> <547B154D.70802@eftlab.co.uk> <547B1932.30701@eftlab.co.uk> Message-ID: <547C2800.2090606@eftlab.co.uk> Hello Jussi, We've been able to reproduce all test vectors from https://github.com/Cloudera-Intel-QA-Transition/test-cases/wiki/Diceros-Test-Cases . All went well except for AES128 decode in CBC mode. This is strange as the same code does very well for AES 192 & 256. Would you mind if I'll ask you to confirm on following vector? KEY = 0700d603a1c514e46b6191ba430a3a0c IV = aad1583cd91365e3bb2f0c3430d065bb PLAINTEXT = 068b25c7bfb1f8bdd4cfc908f69dffc5ddc726a197f0e5f720f730393279be91 CIPHERTEXT = c4dc61d9725967a3020104a9738f23868527ce839aab1752fd8bdb95a82c4d00 Which should be hopefully something like this: + { GCRY_CIPHER_AES128, + "\x07\x00\xd6\x03\xa1\xc5\x14\xe4\x6b\x61\x91\xba\x43\x0a\x3a\x0c", + "\xaa\xd1\x58\x3c\xd9\x13\x65\xe3\xbb\x2f\x0c\x34\x30\xd0\x65\xbb", + { { "\x06\x8b\x25\xc7\xbf\xb1\xf8\xbd\xd4\xcf\xc9\x08\xf6\x9d\xff\xc5" + "\xdd\xc7\x26\xa1\x97\xf0\xe5\xf7\x20\xf7\x30\x39\x32\x79\xbe\x91", + 32, + "\xc4\xdc\x61\xd9\x72\x59\x67\xa3\x02\x01\x04\xa9\x73\x8f\x23\x86" + "\x85\x27\xce\x83\x9a\xab\x17\x52\xfd\x8b\xdb\x95\xa8\x2c\x4d\x00" }, + } + }, If you can encode (should do well) and decode the result back. Thank you, Jan Jan Bilek CTO, EFTlab Pty Ltd email:jan.bilek at eftlab.co.uk mob: +61 (0) 498 103 179 This message contains confidential information and is intended only for the addressee(s). E-mail transmission cannot be guaranteed to be secure or error-free as information could be intercepted, corrupted, lost, destroyed, arrive late or incomplete, or contain viruses. EFTlab Ltd cannot accept liability for any errors or omissions in the contents of this message, which may arise as a result of e-mail transmission. Please note that EFTlab Ltd may monitor, analyse and archive email traffic, data and the content of email for the purposes of security, legal compliance and staff training. If you have received this email in error please notify us at support at eftlab.co.uk. EFTlab is a limited company registered in England & Wales with Reg No. 07528943. The Registered Office is 21-27 Lamb's Conduit Street, London, WC1N 3GS. -------------- next part -------------- An HTML attachment was scrubbed... URL: From jussi.kivilinna at iki.fi Mon Dec 1 18:30:02 2014 From: jussi.kivilinna at iki.fi (Jussi Kivilinna) Date: Mon, 01 Dec 2014 19:30:02 +0200 Subject: AES128 in CBC mode decode on longer data [libgcrypt] In-Reply-To: <547C2800.2090606@eftlab.co.uk> References: <5477CB7C.6020507@eftlab.co.uk> <547ADE44.2020907@iki.fi> <547B154D.70802@eftlab.co.uk> <547B1932.30701@eftlab.co.uk> <547C2800.2090606@eftlab.co.uk> Message-ID: <547CA59A.9080809@iki.fi> On 01.12.2014 10:34, Jan Bilek wrote: > Hello Jussi, > > We've been able to reproduce all test vectors from https://github.com/Cloudera-Intel-QA-Transition/test-cases/wiki/Diceros-Test-Cases . > > All went well except for AES128 decode in CBC mode. This is strange as the same code does very well for AES 192 & 256. > > Would you mind if I'll ask you to confirm on following vector? > > KEY = 0700d603a1c514e46b6191ba430a3a0c > IV = aad1583cd91365e3bb2f0c3430d065bb > PLAINTEXT = 068b25c7bfb1f8bdd4cfc908f69dffc5ddc726a197f0e5f720f730393279be91 > CIPHERTEXT = c4dc61d9725967a3020104a9738f23868527ce839aab1752fd8bdb95a82c4d00 > > Which should be hopefully something like this: > > + { GCRY_CIPHER_AES128, > + "\x07\x00\xd6\x03\xa1\xc5\x14\xe4\x6b\x61\x91\xba\x43\x0a\x3a\x0c", > + "\xaa\xd1\x58\x3c\xd9\x13\x65\xe3\xbb\x2f\x0c\x34\x30\xd0\x65\xbb", > + { { "\x06\x8b\x25\xc7\xbf\xb1\xf8\xbd\xd4\xcf\xc9\x08\xf6\x9d\xff\xc5" > + "\xdd\xc7\x26\xa1\x97\xf0\xe5\xf7\x20\xf7\x30\x39\x32\x79\xbe\x91", > + 32, > + "\xc4\xdc\x61\xd9\x72\x59\x67\xa3\x02\x01\x04\xa9\x73\x8f\x23\x86" > + "\x85\x27\xce\x83\x9a\xab\x17\x52\xfd\x8b\xdb\x95\xa8\x2c\x4d\x00" }, > + } > + }, > > If you can encode (should do well) and decode the result back. Yes, I get correct results in tests/basic.c with that test vector. -Jussi > > Thank you, > Jan > > Jan Bilek > CTO, EFTlab Pty Ltd > email: jan.bilek at eftlab.co.uk > mob: +61 (0) 498 103 179 > > This message contains confidential information and is intended only for the addressee(s). E-mail transmission cannot be guaranteed to be secure or error-free as information could be intercepted, corrupted, lost, destroyed, arrive late or incomplete, or contain viruses. EFTlab Ltd cannot accept liability for any errors or omissions in the contents of this message, which may arise as a result of e-mail transmission. Please note that EFTlab Ltd may monitor, analyse and archive email traffic, data and the content of email for the purposes of security, legal compliance and staff training. If you have received this email in error please notify us at support at eftlab.co.uk. EFTlab is a limited company registered in England & Wales with Reg No. 07528943. The Registered Office is 21-27 Lamb's Conduit Street, London, WC1N 3GS. > > > _______________________________________________ > Gcrypt-devel mailing list > Gcrypt-devel at gnupg.org > http://lists.gnupg.org/mailman/listinfo/gcrypt-devel > -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 648 bytes Desc: OpenPGP digital signature URL: From jussi.kivilinna at iki.fi Mon Dec 1 20:12:52 2014 From: jussi.kivilinna at iki.fi (Jussi Kivilinna) Date: Mon, 01 Dec 2014 21:12:52 +0200 Subject: [PATCH 3/4] rijndael: refactor to reduce number of #ifdefs and branches In-Reply-To: <20141201191241.29171.92795.stgit@localhost6.localdomain6> References: <20141201191241.29171.92795.stgit@localhost6.localdomain6> Message-ID: <20141201191252.29171.84690.stgit@localhost6.localdomain6> * cipher/rijndael-aesni.c (_gcry_aes_aesni_encrypt) (_gcry_aes_aesni_decrypt): Make return stack burn depth. * cipher/rijndael-amd64.S (_gcry_aes_amd64_encrypt_block) (_gcry_aes_amd64_decrypt_block): Ditto. * cipher/rijndael-arm.S (_gcry_aes_arm_encrypt_block) (_gcry_aes_arm_decrypt_block): Ditto. * cipher/rijndael-internal.h (RIJNDAEL_context_s) (rijndael_cryptfn_t): New. (RIJNDAEL_context): New members 'encrypt_fn' and 'decrypt_fn'. * cipher/rijndael.c (_gcry_aes_amd64_encrypt_block) (_gcry_aes_amd64_decrypt_block, _gcry_aes_aesni_encrypt) (_gcry_aes_aesni_decrypt, _gcry_aes_arm_encrypt_block) (_gcry_aes_arm_decrypt_block): Change prototypes. (do_padlock_encrypt, do_padlock_decrypt): New. (do_setkey): Separate key-length to rounds conversion from HW features check; Add selection for ctx->encrypt_fn and ctx->decrypt_fn. (do_encrypt_aligned, do_decrypt_aligned): Move inside '[!USE_AMD64_ASM && !USE_ARM_ASM]'; Move USE_AMD64_ASM and USE_ARM_ASM to... (do_encrypt, do_decrypt): ...here; Return stack depth; Remove second temporary buffer from non-aligned input/output case. (do_padlock): Move decrypt_flag to last argument; Return stack depth. (rijndael_encrypt): Remove #ifdefs, just call ctx->encrypt_fn. (_gcry_aes_cfb_enc, _gcry_aes_cbc_enc): Remove USE_PADLOCK; Call ctx->encrypt_fn in place of do_encrypt/do_encrypt_aligned. (_gcry_aes_ctr_enc): Call ctx->encrypt_fn in place of do_encrypt_aligned; Make tmp buffer 16-byte aligned and wipe buffer after use. (rijndael_encrypt): Remove #ifdefs, just call ctx->decrypt_fn. (_gcry_aes_cfb_dec): Remove USE_PADLOCK; Call ctx->decrypt_fn in place of do_decrypt/do_decrypt_aligned. (_gcry_aes_cbc_dec): Ditto; Make savebuf buffer 16-byte aligned. -- Signed-off-by: Jussi Kivilinna --- cipher/rijndael-aesni.c | 10 + cipher/rijndael-amd64.S | 2 cipher/rijndael-arm.S | 3 cipher/rijndael-internal.h | 11 + cipher/rijndael.c | 361 ++++++++++++++++++-------------------------- 5 files changed, 164 insertions(+), 223 deletions(-) diff --git a/cipher/rijndael-aesni.c b/cipher/rijndael-aesni.c index 15ed4ad..e6c1051 100644 --- a/cipher/rijndael-aesni.c +++ b/cipher/rijndael-aesni.c @@ -1021,13 +1021,14 @@ do_aesni_ctr_4 (const RIJNDAEL_context *ctx, } -void -_gcry_aes_aesni_encrypt (RIJNDAEL_context *ctx, unsigned char *dst, +unsigned int +_gcry_aes_aesni_encrypt (const RIJNDAEL_context *ctx, unsigned char *dst, const unsigned char *src) { aesni_prepare (); do_aesni_enc (ctx, dst, src); aesni_cleanup (); + return 0; } @@ -1128,13 +1129,14 @@ _gcry_aes_aesni_ctr_enc (RIJNDAEL_context *ctx, unsigned char *outbuf, } -void -_gcry_aes_aesni_decrypt (RIJNDAEL_context *ctx, unsigned char *dst, +unsigned int +_gcry_aes_aesni_decrypt (const RIJNDAEL_context *ctx, unsigned char *dst, const unsigned char *src) { aesni_prepare (); do_aesni_dec (ctx, dst, src); aesni_cleanup (); + return 0; } diff --git a/cipher/rijndael-amd64.S b/cipher/rijndael-amd64.S index 16a1ffd..90e804b 100644 --- a/cipher/rijndael-amd64.S +++ b/cipher/rijndael-amd64.S @@ -212,6 +212,7 @@ _gcry_aes_amd64_encrypt_block: movq (2 * 8)(%rsp), %rbp; addq $(5 * 8), %rsp; + movl $(6 * 8), %eax; ret; .align 4 @@ -334,6 +335,7 @@ _gcry_aes_amd64_decrypt_block: movq (2 * 8)(%rsp), %rbp; addq $(5 * 8), %rsp; + movl $(6 * 8), %eax; ret; .align 4 diff --git a/cipher/rijndael-arm.S b/cipher/rijndael-arm.S index 6004ce8..c385e67 100644 --- a/cipher/rijndael-arm.S +++ b/cipher/rijndael-arm.S @@ -314,6 +314,8 @@ _gcry_aes_arm_encrypt_block: /* write output block */ stm RT0, {RA, RB, RC, RD}; 2: + + mov r0, #(10 * 4); pop {%r4-%r11, %ip, %pc}; .ltorg @@ -565,6 +567,7 @@ _gcry_aes_arm_decrypt_block: /* write output block */ stm RT0, {RA, RB, RC, RD}; 2: + mov r0, #(10 * 4); pop {%r4-%r11, %ip, %pc}; .ltorg diff --git a/cipher/rijndael-internal.h b/cipher/rijndael-internal.h index 762ea76..9898f0c 100644 --- a/cipher/rijndael-internal.h +++ b/cipher/rijndael-internal.h @@ -74,9 +74,14 @@ # endif #endif /* ENABLE_AESNI_SUPPORT */ +struct RIJNDAEL_context_s; + +typedef unsigned int (*rijndael_cryptfn_t)(const struct RIJNDAEL_context_s *ctx, + unsigned char *bx, + const unsigned char *ax); /* Our context object. */ -typedef struct +typedef struct RIJNDAEL_context_s { /* The first fields are the keyschedule arrays. This is so that they are aligned on a 16 byte boundary if using gcc. This @@ -100,7 +105,7 @@ typedef struct PROPERLY_ALIGNED_TYPE dummy; byte keyschedule[MAXROUNDS+1][4][4]; } u2; - int rounds; /* Key-length-dependent number of rounds. */ + int rounds; /* Key-length-dependent number of rounds. */ unsigned int decryption_prepared:1; /* The decryption key schedule is available. */ #ifdef USE_PADLOCK unsigned int use_padlock:1; /* Padlock shall be used. */ @@ -108,6 +113,8 @@ typedef struct #ifdef USE_AESNI unsigned int use_aesni:1; /* AES-NI shall be used. */ #endif /*USE_AESNI*/ + rijndael_cryptfn_t encrypt_fn; + rijndael_cryptfn_t decrypt_fn; } RIJNDAEL_context ATTR_ALIGNED_16; /* Macros defining alias for the keyschedules. */ diff --git a/cipher/rijndael.c b/cipher/rijndael.c index 8a76fad..f45171a 100644 --- a/cipher/rijndael.c +++ b/cipher/rijndael.c @@ -60,15 +60,15 @@ typedef u32 u32_a_t; #ifdef USE_AMD64_ASM /* AMD64 assembly implementations of AES */ -extern void _gcry_aes_amd64_encrypt_block(const void *keysched_enc, - unsigned char *out, - const unsigned char *in, - int rounds); - -extern void _gcry_aes_amd64_decrypt_block(const void *keysched_dec, - unsigned char *out, - const unsigned char *in, - int rounds); +extern unsigned int _gcry_aes_amd64_encrypt_block(const void *keysched_enc, + unsigned char *out, + const unsigned char *in, + int rounds); + +extern unsigned int _gcry_aes_amd64_decrypt_block(const void *keysched_dec, + unsigned char *out, + const unsigned char *in, + int rounds); #endif /*USE_AMD64_ASM*/ #ifdef USE_AESNI @@ -76,10 +76,12 @@ extern void _gcry_aes_amd64_decrypt_block(const void *keysched_dec, extern void _gcry_aes_aesni_do_setkey(RIJNDAEL_context *ctx, const byte *key); extern void _gcry_aes_aesni_prepare_decryption(RIJNDAEL_context *ctx); -extern void _gcry_aes_aesni_encrypt (RIJNDAEL_context *ctx, unsigned char *dst, - const unsigned char *src); -extern void _gcry_aes_aesni_decrypt (RIJNDAEL_context *ctx, unsigned char *dst, - const unsigned char *src); +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 (RIJNDAEL_context *ctx, unsigned char *outbuf, const unsigned char *inbuf, @@ -103,19 +105,33 @@ extern void _gcry_aes_aesni_cbc_dec (RIJNDAEL_context *ctx, unsigned char *iv, size_t nblocks); #endif +#ifdef USE_PADLOCK +static unsigned int do_padlock_encrypt (const RIJNDAEL_context *ctx, + unsigned char *bx, + const unsigned char *ax); +static unsigned int do_padlock_decrypt (const RIJNDAEL_context *ctx, + unsigned char *bx, + const unsigned char *ax); +#endif + #ifdef USE_ARM_ASM /* ARM assembly implementations of AES */ -extern void _gcry_aes_arm_encrypt_block(const void *keysched_enc, - unsigned char *out, - const unsigned char *in, - int rounds); - -extern void _gcry_aes_arm_decrypt_block(const void *keysched_dec, - unsigned char *out, - const unsigned char *in, - int rounds); +extern unsigned int _gcry_aes_arm_encrypt_block(const void *keysched_enc, + unsigned char *out, + const unsigned char *in, + int rounds); + +extern unsigned int _gcry_aes_arm_decrypt_block(const void *keysched_dec, + unsigned char *out, + const unsigned char *in, + int rounds); #endif /*USE_ARM_ASM*/ +static unsigned int do_encrypt (const RIJNDAEL_context *ctx, unsigned char *bx, + const unsigned char *ax); +static unsigned int do_decrypt (const RIJNDAEL_context *ctx, unsigned char *bx, + const unsigned char *ax); + /* All the numbers. */ @@ -159,6 +175,26 @@ do_setkey (RIJNDAEL_context *ctx, const byte *key, const unsigned keylen) if (selftest_failed) return GPG_ERR_SELFTEST_FAILED; + if( keylen == 128/8 ) + { + rounds = 10; + KC = 4; + } + else if ( keylen == 192/8 ) + { + rounds = 12; + KC = 6; + } + else if ( keylen == 256/8 ) + { + rounds = 14; + KC = 8; + } + else + return GPG_ERR_INV_KEYLEN; + + ctx->rounds = rounds; + #if defined(USE_AESNI) || defined(USE_PADLOCK) hwfeatures = _gcry_get_hw_features (); #endif @@ -171,65 +207,32 @@ do_setkey (RIJNDAEL_context *ctx, const byte *key, const unsigned keylen) ctx->use_aesni = 0; #endif - if( keylen == 128/8 ) + if (0) { - rounds = 10; - KC = 4; - - if (0) - { - ; - } + ; + } #ifdef USE_AESNI - else if (hwfeatures & HWF_INTEL_AESNI) - { - ctx->use_aesni = 1; - } + else if (hwfeatures & HWF_INTEL_AESNI) + { + ctx->encrypt_fn = _gcry_aes_aesni_encrypt; + ctx->decrypt_fn = _gcry_aes_aesni_decrypt; + ctx->use_aesni = 1; + } #endif #ifdef USE_PADLOCK - else if (hwfeatures & HWF_PADLOCK_AES) - { - ctx->use_padlock = 1; - memcpy (ctx->padlockkey, key, keylen); - } -#endif - } - else if ( keylen == 192/8 ) + else if (hwfeatures & HWF_PADLOCK_AES && keylen == 128/8) { - rounds = 12; - KC = 6; - - if (0) - { - ; - } -#ifdef USE_AESNI - else if (hwfeatures & HWF_INTEL_AESNI) - { - ctx->use_aesni = 1; - } -#endif + ctx->encrypt_fn = do_padlock_encrypt; + ctx->decrypt_fn = do_padlock_decrypt; + ctx->use_padlock = 1; + memcpy (ctx->padlockkey, key, keylen); } - else if ( keylen == 256/8 ) - { - rounds = 14; - KC = 8; - - if (0) - { - ; - } -#ifdef USE_AESNI - else if (hwfeatures & HWF_INTEL_AESNI) - { - ctx->use_aesni = 1; - } #endif - } else - return GPG_ERR_INV_KEYLEN; - - ctx->rounds = rounds; + { + ctx->encrypt_fn = do_encrypt; + ctx->decrypt_fn = do_decrypt; + } /* NB: We don't yet support Padlock hardware key generation. */ @@ -404,17 +407,13 @@ prepare_decryption( RIJNDAEL_context *ctx ) } +#if !defined(USE_AMD64_ASM) && !defined(USE_ARM_ASM) /* Encrypt one block. A and B need to be aligned on a 4 byte boundary. A and B may be the same. */ static void do_encrypt_aligned (const RIJNDAEL_context *ctx, unsigned char *b, const unsigned char *a) { -#ifdef USE_AMD64_ASM - _gcry_aes_amd64_encrypt_block(ctx->keyschenc, b, a, ctx->rounds); -#elif defined(USE_ARM_ASM) - _gcry_aes_arm_encrypt_block(ctx->keyschenc, b, a, ctx->rounds); -#else #define rk (ctx->keyschenc) int rounds = ctx->rounds; int r; @@ -496,15 +495,19 @@ do_encrypt_aligned (const RIJNDAEL_context *ctx, *((u32_a_t*)(b+ 8)) ^= *((u32_a_t*)rk[rounds][2]); *((u32_a_t*)(b+12)) ^= *((u32_a_t*)rk[rounds][3]); #undef rk -#endif /*!USE_AMD64_ASM && !USE_ARM_ASM*/ } +#endif /*!USE_AMD64_ASM && !USE_ARM_ASM*/ -static void +static unsigned int do_encrypt (const RIJNDAEL_context *ctx, unsigned char *bx, const unsigned char *ax) { -#if !defined(USE_AMD64_ASM) && !defined(USE_ARM_ASM) +#ifdef USE_AMD64_ASM + return _gcry_aes_amd64_encrypt_block(ctx->keyschenc, bx, ax, ctx->rounds); +#elif defined(USE_ARM_ASM) + return _gcry_aes_arm_encrypt_block(ctx->keyschenc, bx, ax, ctx->rounds); +#else /* BX and AX are not necessary correctly aligned. Thus we might need to copy them here. We try to align to a 16 bytes. */ if (((size_t)ax & 0x0f) || ((size_t)bx & 0x0f)) @@ -514,30 +517,27 @@ do_encrypt (const RIJNDAEL_context *ctx, u32 dummy[4]; byte a[16] ATTR_ALIGNED_16; } a; - union - { - u32 dummy[4]; - byte b[16] ATTR_ALIGNED_16; - } b; buf_cpy (a.a, ax, 16); - do_encrypt_aligned (ctx, b.b, a.a); - buf_cpy (bx, b.b, 16); + do_encrypt_aligned (ctx, a.a, a.a); + buf_cpy (bx, a.a, 16); } else -#endif /*!USE_AMD64_ASM && !USE_ARM_ASM*/ { do_encrypt_aligned (ctx, bx, ax); } + + return (56 + 2*sizeof(int)); +#endif /*!USE_AMD64_ASM && !USE_ARM_ASM*/ } /* Encrypt or decrypt one block using the padlock engine. A and B may be the same. */ #ifdef USE_PADLOCK -static void -do_padlock (const RIJNDAEL_context *ctx, int decrypt_flag, - unsigned char *bx, const unsigned char *ax) +static unsigned int +do_padlock (const RIJNDAEL_context *ctx, unsigned char *bx, + const unsigned char *ax, int decrypt_flag) { /* BX and AX are not necessary correctly aligned. Thus we need to copy them here. */ @@ -583,6 +583,21 @@ do_padlock (const RIJNDAEL_context *ctx, int decrypt_flag, memcpy (bx, b, 16); + return (48 + 15 /* possible padding for alignment */); +} + +static unsigned int +do_padlock_encrypt (const RIJNDAEL_context *ctx, + unsigned char *bx, const unsigned char *ax) +{ + return do_padlock(ctx, bx, ax, 0); +} + +static unsigned int +do_padlock_decrypt (const RIJNDAEL_context *ctx, + unsigned char *bx, const unsigned char *ax) +{ + return do_padlock(ctx, bx, ax, 1); } #endif /*USE_PADLOCK*/ @@ -591,31 +606,8 @@ static unsigned int rijndael_encrypt (void *context, byte *b, const byte *a) { RIJNDAEL_context *ctx = context; - unsigned int burn_stack; - - if (0) - ; -#ifdef USE_AESNI - else if (ctx->use_aesni) - { - _gcry_aes_aesni_encrypt (ctx, b, a); - burn_stack = 0; - } -#endif /*USE_AESNI*/ -#ifdef USE_PADLOCK - else if (ctx->use_padlock) - { - do_padlock (ctx, 0, b, a); - burn_stack = (48 + 15 /* possible padding for alignment */); - } -#endif /*USE_PADLOCK*/ - else - { - do_encrypt (ctx, b, a); - burn_stack = (56 + 2*sizeof(int)); - } - return burn_stack; + return ctx->encrypt_fn (ctx, b, a); } @@ -631,7 +623,7 @@ _gcry_aes_cfb_enc (void *context, unsigned char *iv, RIJNDAEL_context *ctx = context; unsigned char *outbuf = outbuf_arg; const unsigned char *inbuf = inbuf_arg; - unsigned int burn_depth = 48 + 2*sizeof(int); + unsigned int burn_depth = 0; if (0) ; @@ -642,27 +634,12 @@ _gcry_aes_cfb_enc (void *context, unsigned char *iv, burn_depth = 0; } #endif /*USE_AESNI*/ -#ifdef USE_PADLOCK - else if (ctx->use_padlock) - { - /* Fixme: Let Padlock do the CFBing. */ - for ( ;nblocks; nblocks-- ) - { - /* Encrypt the IV. */ - do_padlock (ctx, 0, iv, iv); - /* XOR the input with the IV and store input into IV. */ - buf_xor_2dst(outbuf, iv, inbuf, BLOCKSIZE); - outbuf += BLOCKSIZE; - inbuf += BLOCKSIZE; - } - } -#endif /*USE_PADLOCK*/ else { for ( ;nblocks; nblocks-- ) { /* Encrypt the IV. */ - do_encrypt_aligned (ctx, iv, iv); + burn_depth = ctx->encrypt_fn (ctx, iv, iv); /* XOR the input with the IV and store input into IV. */ buf_xor_2dst(outbuf, iv, inbuf, BLOCKSIZE); outbuf += BLOCKSIZE; @@ -671,7 +648,7 @@ _gcry_aes_cfb_enc (void *context, unsigned char *iv, } if (burn_depth) - _gcry_burn_stack (burn_depth); + _gcry_burn_stack (burn_depth + 4 * sizeof(void *)); } @@ -688,7 +665,7 @@ _gcry_aes_cbc_enc (void *context, unsigned char *iv, unsigned char *outbuf = outbuf_arg; const unsigned char *inbuf = inbuf_arg; unsigned char *last_iv; - unsigned int burn_depth = 48 + 2*sizeof(int); + unsigned int burn_depth = 0; if (0) ; @@ -707,14 +684,7 @@ _gcry_aes_cbc_enc (void *context, unsigned char *iv, { buf_xor(outbuf, inbuf, last_iv, BLOCKSIZE); - if (0) - ; -#ifdef USE_PADLOCK - else if (ctx->use_padlock) - do_padlock (ctx, 0, outbuf, outbuf); -#endif /*USE_PADLOCK*/ - else - do_encrypt (ctx, outbuf, outbuf ); + burn_depth = ctx->encrypt_fn (ctx, outbuf, outbuf); last_iv = outbuf; inbuf += BLOCKSIZE; @@ -727,7 +697,7 @@ _gcry_aes_cbc_enc (void *context, unsigned char *iv, } if (burn_depth) - _gcry_burn_stack (burn_depth); + _gcry_burn_stack (burn_depth + 4 * sizeof(void *)); } @@ -744,7 +714,7 @@ _gcry_aes_ctr_enc (void *context, unsigned char *ctr, RIJNDAEL_context *ctx = context; unsigned char *outbuf = outbuf_arg; const unsigned char *inbuf = inbuf_arg; - unsigned int burn_depth = 48 + 2*sizeof(int); + unsigned int burn_depth = 0; int i; if (0) @@ -758,12 +728,12 @@ _gcry_aes_ctr_enc (void *context, unsigned char *ctr, #endif /*USE_AESNI*/ else { - union { unsigned char x1[16]; u32 x32[4]; } tmp; + union { unsigned char x1[16] ATTR_ALIGNED_16; u32 x32[4]; } tmp; for ( ;nblocks; nblocks-- ) { /* Encrypt the counter. */ - do_encrypt_aligned (ctx, tmp.x1, ctr); + burn_depth = ctx->encrypt_fn (ctx, tmp.x1, ctr); /* XOR the input with the encrypted counter and store in output. */ buf_xor(outbuf, tmp.x1, inbuf, BLOCKSIZE); outbuf += BLOCKSIZE; @@ -776,26 +746,24 @@ _gcry_aes_ctr_enc (void *context, unsigned char *ctr, break; } } + + wipememory(&tmp, sizeof(tmp)); } if (burn_depth) - _gcry_burn_stack (burn_depth); + _gcry_burn_stack (burn_depth + 4 * sizeof(void *)); } +#if !defined(USE_AMD64_ASM) && !defined(USE_ARM_ASM) /* Decrypt one block. A and B need to be aligned on a 4 byte boundary and the decryption must have been prepared. A and B may be the same. */ static void -do_decrypt_aligned (RIJNDAEL_context *ctx, +do_decrypt_aligned (const RIJNDAEL_context *ctx, unsigned char *b, const unsigned char *a) { -#ifdef USE_AMD64_ASM - _gcry_aes_amd64_decrypt_block(ctx->keyschdec, b, a, ctx->rounds); -#elif defined(USE_ARM_ASM) - _gcry_aes_arm_decrypt_block(ctx->keyschdec, b, a, ctx->rounds); -#else #define rk (ctx->keyschdec) int rounds = ctx->rounds; int r; @@ -878,15 +846,20 @@ do_decrypt_aligned (RIJNDAEL_context *ctx, *((u32_a_t*)(b+ 8)) ^= *((u32_a_t*)rk[0][2]); *((u32_a_t*)(b+12)) ^= *((u32_a_t*)rk[0][3]); #undef rk -#endif /*!USE_AMD64_ASM && !USE_ARM_ASM*/ } +#endif /*!USE_AMD64_ASM && !USE_ARM_ASM*/ /* Decrypt one block. AX and BX may be the same. */ -static void -do_decrypt (RIJNDAEL_context *ctx, byte *bx, const byte *ax) +static unsigned int +do_decrypt (const RIJNDAEL_context *ctx, unsigned char *bx, + const unsigned char *ax) { -#if !defined(USE_AMD64_ASM) && !defined(USE_ARM_ASM) +#ifdef USE_AMD64_ASM + return _gcry_aes_amd64_decrypt_block(ctx->keyschdec, bx, ax, ctx->rounds); +#elif defined(USE_ARM_ASM) + return _gcry_aes_arm_decrypt_block(ctx->keyschdec, bx, ax, ctx->rounds); +#else /* BX and AX are not necessary correctly aligned. Thus we might need to copy them here. We try to align to a 16 bytes. */ if (((size_t)ax & 0x0f) || ((size_t)bx & 0x0f)) @@ -896,21 +869,18 @@ do_decrypt (RIJNDAEL_context *ctx, byte *bx, const byte *ax) u32 dummy[4]; byte a[16] ATTR_ALIGNED_16; } a; - union - { - u32 dummy[4]; - byte b[16] ATTR_ALIGNED_16; - } b; buf_cpy (a.a, ax, 16); - do_decrypt_aligned (ctx, b.b, a.a); - buf_cpy (bx, b.b, 16); + do_decrypt_aligned (ctx, a.a, a.a); + buf_cpy (bx, a.a, 16); } else -#endif /*!USE_AMD64_ASM && !USE_ARM_ASM*/ { do_decrypt_aligned (ctx, bx, ax); } + + return (56+2*sizeof(int)); +#endif /*!USE_AMD64_ASM && !USE_ARM_ASM*/ } @@ -929,33 +899,10 @@ static unsigned int rijndael_decrypt (void *context, byte *b, const byte *a) { RIJNDAEL_context *ctx = context; - unsigned int burn_stack; check_decryption_preparation (ctx); - if (0) - ; -#ifdef USE_AESNI - else if (ctx->use_aesni) - { - _gcry_aes_aesni_decrypt (ctx, b, a); - burn_stack = 0; - } -#endif /*USE_AESNI*/ -#ifdef USE_PADLOCK - else if (ctx->use_padlock) - { - do_padlock (ctx, 1, b, a); - burn_stack = (48 + 2*sizeof(int) /* FIXME */); - } -#endif /*USE_PADLOCK*/ - else - { - do_decrypt (ctx, b, a); - burn_stack = (56+2*sizeof(int)); - } - - return burn_stack; + return ctx->decrypt_fn (ctx, b, a); } @@ -971,7 +918,7 @@ _gcry_aes_cfb_dec (void *context, unsigned char *iv, RIJNDAEL_context *ctx = context; unsigned char *outbuf = outbuf_arg; const unsigned char *inbuf = inbuf_arg; - unsigned int burn_depth = 48 + 2*sizeof(int); + unsigned int burn_depth = 0; if (0) ; @@ -982,24 +929,11 @@ _gcry_aes_cfb_dec (void *context, unsigned char *iv, burn_depth = 0; } #endif /*USE_AESNI*/ -#ifdef USE_PADLOCK - else if (ctx->use_padlock) - { - /* Fixme: Let Padlock do the CFBing. */ - for ( ;nblocks; nblocks-- ) - { - do_padlock (ctx, 0, iv, iv); - buf_xor_n_copy(outbuf, iv, inbuf, BLOCKSIZE); - outbuf += BLOCKSIZE; - inbuf += BLOCKSIZE; - } - } -#endif /*USE_PADLOCK*/ else { for ( ;nblocks; nblocks-- ) { - do_encrypt_aligned (ctx, iv, iv); + burn_depth = ctx->encrypt_fn (ctx, iv, iv); buf_xor_n_copy(outbuf, iv, inbuf, BLOCKSIZE); outbuf += BLOCKSIZE; inbuf += BLOCKSIZE; @@ -1007,7 +941,7 @@ _gcry_aes_cfb_dec (void *context, unsigned char *iv, } if (burn_depth) - _gcry_burn_stack (burn_depth); + _gcry_burn_stack (burn_depth + 4 * sizeof(void *)); } @@ -1023,7 +957,7 @@ _gcry_aes_cbc_dec (void *context, unsigned char *iv, RIJNDAEL_context *ctx = context; unsigned char *outbuf = outbuf_arg; const unsigned char *inbuf = inbuf_arg; - unsigned int burn_depth = 48 + 2*sizeof(int) + 4*sizeof (char*); + unsigned int burn_depth = 0; check_decryption_preparation (ctx); @@ -1038,21 +972,14 @@ _gcry_aes_cbc_dec (void *context, unsigned char *iv, #endif /*USE_AESNI*/ else { - unsigned char savebuf[BLOCKSIZE]; + unsigned char savebuf[BLOCKSIZE] ATTR_ALIGNED_16; for ( ;nblocks; nblocks-- ) { /* INBUF is needed later and it may be identical to OUTBUF, so store the intermediate result to SAVEBUF. */ - if (0) - ; -#ifdef USE_PADLOCK - else if (ctx->use_padlock) - do_padlock (ctx, 1, savebuf, inbuf); -#endif /*USE_PADLOCK*/ - else - do_decrypt (ctx, savebuf, inbuf); + burn_depth = ctx->decrypt_fn (ctx, savebuf, inbuf); buf_xor_n_copy_2(outbuf, savebuf, iv, inbuf, BLOCKSIZE); inbuf += BLOCKSIZE; @@ -1063,7 +990,7 @@ _gcry_aes_cbc_dec (void *context, unsigned char *iv, } if (burn_depth) - _gcry_burn_stack (burn_depth); + _gcry_burn_stack (burn_depth + 4 * sizeof(void *)); } From jussi.kivilinna at iki.fi Mon Dec 1 20:12:47 2014 From: jussi.kivilinna at iki.fi (Jussi Kivilinna) Date: Mon, 01 Dec 2014 21:12:47 +0200 Subject: [PATCH 2/4] rijndael: move AES-NI blocks before Padlock In-Reply-To: <20141201191241.29171.92795.stgit@localhost6.localdomain6> References: <20141201191241.29171.92795.stgit@localhost6.localdomain6> Message-ID: <20141201191247.29171.45294.stgit@localhost6.localdomain6> * cipher/rijndael.c (do_setkey, rijndael_encrypt, _gcry_aes_cfb_enc) (rijndael_decrypt, _gcry_aes_cfb_dec): Move USE_AESNI before USE_PADLOCK. (check_decryption_praparation) [USE_PADLOCK]: Move to... (prepare_decryption) [USE_PADLOCK]: ...here. -- Make order of AES-NI and Padlock #ifdefs consistent. Signed-off-by: Jussi Kivilinna --- cipher/rijndael.c | 88 +++++++++++++++++++++++++++-------------------------- 1 file changed, 45 insertions(+), 43 deletions(-) diff --git a/cipher/rijndael.c b/cipher/rijndael.c index 4a10a6b..8a76fad 100644 --- a/cipher/rijndael.c +++ b/cipher/rijndael.c @@ -180,6 +180,12 @@ do_setkey (RIJNDAEL_context *ctx, const byte *key, const unsigned keylen) { ; } +#ifdef USE_AESNI + else if (hwfeatures & HWF_INTEL_AESNI) + { + ctx->use_aesni = 1; + } +#endif #ifdef USE_PADLOCK else if (hwfeatures & HWF_PADLOCK_AES) { @@ -187,12 +193,6 @@ do_setkey (RIJNDAEL_context *ctx, const byte *key, const unsigned keylen) memcpy (ctx->padlockkey, key, keylen); } #endif -#ifdef USE_AESNI - else if (hwfeatures & HWF_INTEL_AESNI) - { - ctx->use_aesni = 1; - } -#endif } else if ( keylen == 192/8 ) { @@ -348,13 +348,21 @@ prepare_decryption( RIJNDAEL_context *ctx ) { int r; + if (0) + ; #ifdef USE_AESNI - if (ctx->use_aesni) + else if (ctx->use_aesni) { _gcry_aes_aesni_prepare_decryption (ctx); } - else #endif /*USE_AESNI*/ +#ifdef USE_PADLOCK + else if (ctx->use_padlock) + { + /* Padlock does not need decryption subkeys. */ + } +#endif /*USE_PADLOCK*/ + else { union { @@ -587,13 +595,6 @@ rijndael_encrypt (void *context, byte *b, const byte *a) if (0) ; -#ifdef USE_PADLOCK - else if (ctx->use_padlock) - { - do_padlock (ctx, 0, b, a); - burn_stack = (48 + 15 /* possible padding for alignment */); - } -#endif /*USE_PADLOCK*/ #ifdef USE_AESNI else if (ctx->use_aesni) { @@ -601,6 +602,13 @@ rijndael_encrypt (void *context, byte *b, const byte *a) burn_stack = 0; } #endif /*USE_AESNI*/ +#ifdef USE_PADLOCK + else if (ctx->use_padlock) + { + do_padlock (ctx, 0, b, a); + burn_stack = (48 + 15 /* possible padding for alignment */); + } +#endif /*USE_PADLOCK*/ else { do_encrypt (ctx, b, a); @@ -627,6 +635,13 @@ _gcry_aes_cfb_enc (void *context, unsigned char *iv, if (0) ; +#ifdef USE_AESNI + else if (ctx->use_aesni) + { + _gcry_aes_aesni_cfb_enc (ctx, outbuf, inbuf, iv, nblocks); + burn_depth = 0; + } +#endif /*USE_AESNI*/ #ifdef USE_PADLOCK else if (ctx->use_padlock) { @@ -642,13 +657,6 @@ _gcry_aes_cfb_enc (void *context, unsigned char *iv, } } #endif /*USE_PADLOCK*/ -#ifdef USE_AESNI - else if (ctx->use_aesni) - { - _gcry_aes_aesni_cfb_enc (ctx, outbuf, inbuf, iv, nblocks); - burn_depth = 0; - } -#endif /*USE_AESNI*/ else { for ( ;nblocks; nblocks-- ) @@ -909,13 +917,7 @@ do_decrypt (RIJNDAEL_context *ctx, byte *bx, const byte *ax) static inline void check_decryption_preparation (RIJNDAEL_context *ctx) { - if (0) - ; -#ifdef USE_PADLOCK - else if (ctx->use_padlock) - { /* Padlock does not need decryption subkeys. */ } -#endif /*USE_PADLOCK*/ - else if ( !ctx->decryption_prepared ) + if ( !ctx->decryption_prepared ) { prepare_decryption ( ctx ); ctx->decryption_prepared = 1; @@ -933,13 +935,6 @@ rijndael_decrypt (void *context, byte *b, const byte *a) if (0) ; -#ifdef USE_PADLOCK - else if (ctx->use_padlock) - { - do_padlock (ctx, 1, b, a); - burn_stack = (48 + 2*sizeof(int) /* FIXME */); - } -#endif /*USE_PADLOCK*/ #ifdef USE_AESNI else if (ctx->use_aesni) { @@ -947,6 +942,13 @@ rijndael_decrypt (void *context, byte *b, const byte *a) burn_stack = 0; } #endif /*USE_AESNI*/ +#ifdef USE_PADLOCK + else if (ctx->use_padlock) + { + do_padlock (ctx, 1, b, a); + burn_stack = (48 + 2*sizeof(int) /* FIXME */); + } +#endif /*USE_PADLOCK*/ else { do_decrypt (ctx, b, a); @@ -973,6 +975,13 @@ _gcry_aes_cfb_dec (void *context, unsigned char *iv, if (0) ; +#ifdef USE_AESNI + else if (ctx->use_aesni) + { + _gcry_aes_aesni_cfb_dec (ctx, outbuf, inbuf, iv, nblocks); + burn_depth = 0; + } +#endif /*USE_AESNI*/ #ifdef USE_PADLOCK else if (ctx->use_padlock) { @@ -986,13 +995,6 @@ _gcry_aes_cfb_dec (void *context, unsigned char *iv, } } #endif /*USE_PADLOCK*/ -#ifdef USE_AESNI - else if (ctx->use_aesni) - { - _gcry_aes_aesni_cfb_dec (ctx, outbuf, inbuf, iv, nblocks); - burn_depth = 0; - } -#endif /*USE_AESNI*/ else { for ( ;nblocks; nblocks-- ) From jussi.kivilinna at iki.fi Mon Dec 1 20:12:57 2014 From: jussi.kivilinna at iki.fi (Jussi Kivilinna) Date: Mon, 01 Dec 2014 21:12:57 +0200 Subject: [PATCH 4/4] rijndael: split Padlock part to separate file In-Reply-To: <20141201191241.29171.92795.stgit@localhost6.localdomain6> References: <20141201191241.29171.92795.stgit@localhost6.localdomain6> Message-ID: <20141201191257.29171.2440.stgit@localhost6.localdomain6> * cipher/Makefile.am: Add 'rijndael-padlock.c'. * cipher/rijndael-padlock.c: New. * cipher/rijndael.c (do_padlock, do_padlock_encrypt) (do_padlock_decrypt): Move to 'rijndael-padlock.c'. * configure.ac [mpi_cpu_arch=x86]: Add 'rijndael-padlock.lo'. -- Signed-off-by: Jussi Kivilinna --- cipher/Makefile.am | 2 - cipher/rijndael-padlock.c | 102 +++++++++++++++++++++++++++++++++++++++++++++ cipher/rijndael.c | 86 ++++---------------------------------- configure.ac | 3 + 4 files changed, 114 insertions(+), 79 deletions(-) create mode 100644 cipher/rijndael-padlock.c diff --git a/cipher/Makefile.am b/cipher/Makefile.am index 19b3692..d7e7773 100644 --- a/cipher/Makefile.am +++ b/cipher/Makefile.am @@ -75,7 +75,7 @@ md4.c \ md5.c \ poly1305-sse2-amd64.S poly1305-avx2-amd64.S poly1305-armv7-neon.S \ rijndael.c rijndael-internal.h rijndael-tables.h rijndael-aesni.c \ - rijndael-amd64.S rijndael-arm.S \ + rijndael-padlock.c rijndael-amd64.S rijndael-arm.S \ rmd160.c \ rsa.c \ salsa20.c salsa20-amd64.S salsa20-armv7-neon.S \ diff --git a/cipher/rijndael-padlock.c b/cipher/rijndael-padlock.c new file mode 100644 index 0000000..476772a --- /dev/null +++ b/cipher/rijndael-padlock.c @@ -0,0 +1,102 @@ +/* Padlock accelerated AES for Libgcrypt + * Copyright (C) 2000, 2001, 2002, 2003, 2007, + * 2008, 2011, 2012 Free Software Foundation, Inc. + * + * This file is part of Libgcrypt. + * + * Libgcrypt is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * Libgcrypt is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, see . + */ + +#include +#include +#include +#include /* for memcmp() */ + +#include "types.h" /* for byte and u32 typedefs */ +#include "g10lib.h" +#include "cipher.h" +#include "bufhelp.h" +#include "cipher-selftest.h" +#include "rijndael-internal.h" + +#ifdef USE_PADLOCK + +/* Encrypt or decrypt one block using the padlock engine. A and B may + be the same. */ +static unsigned int +do_padlock (const RIJNDAEL_context *ctx, unsigned char *bx, + const unsigned char *ax, int decrypt_flag) +{ + /* BX and AX are not necessary correctly aligned. Thus we need to + copy them here. */ + unsigned char a[16] __attribute__ ((aligned (16))); + unsigned char b[16] __attribute__ ((aligned (16))); + unsigned int cword[4] __attribute__ ((aligned (16))); + int blocks; + + /* The control word fields are: + 127:12 11:10 9 8 7 6 5 4 3:0 + RESERVED KSIZE CRYPT INTER KEYGN CIPHR ALIGN DGEST ROUND */ + cword[0] = (ctx->rounds & 15); /* (The mask is just a safeguard.) */ + cword[1] = 0; + cword[2] = 0; + cword[3] = 0; + if (decrypt_flag) + cword[0] |= 0x00000200; + + memcpy (a, ax, 16); + + blocks = 1; /* Init counter for just one block. */ +#ifdef __x86_64__ + asm volatile + ("pushfq\n\t" /* Force key reload. */ + "popfq\n\t" + ".byte 0xf3, 0x0f, 0xa7, 0xc8\n\t" /* REP XCRYPT ECB. */ + : /* No output */ + : "S" (a), "D" (b), "d" (cword), "b" (ctx->padlockkey), "c" (blocks) + : "cc", "memory" + ); +#else + asm volatile + ("pushfl\n\t" /* Force key reload. */ + "popfl\n\t" + "xchg %3, %%ebx\n\t" /* Load key. */ + ".byte 0xf3, 0x0f, 0xa7, 0xc8\n\t" /* REP XCRYPT ECB. */ + "xchg %3, %%ebx\n" /* Restore GOT register. */ + : /* No output */ + : "S" (a), "D" (b), "d" (cword), "r" (ctx->padlockkey), "c" (blocks) + : "cc", "memory" + ); +#endif + + memcpy (bx, b, 16); + + return (48 + 15 /* possible padding for alignment */); +} + +unsigned int +_gcry_aes_padlock_encrypt (const RIJNDAEL_context *ctx, + unsigned char *bx, const unsigned char *ax) +{ + return do_padlock(ctx, bx, ax, 0); +} + +unsigned int +_gcry_aes_padlock_decrypt (const RIJNDAEL_context *ctx, + unsigned char *bx, const unsigned char *ax) +{ + return do_padlock(ctx, bx, ax, 1); +} + +#endif /* USE_PADLOCK */ diff --git a/cipher/rijndael.c b/cipher/rijndael.c index f45171a..9bdb27b 100644 --- a/cipher/rijndael.c +++ b/cipher/rijndael.c @@ -106,12 +106,12 @@ extern void _gcry_aes_aesni_cbc_dec (RIJNDAEL_context *ctx, #endif #ifdef USE_PADLOCK -static unsigned int do_padlock_encrypt (const RIJNDAEL_context *ctx, - unsigned char *bx, - const unsigned char *ax); -static unsigned int do_padlock_decrypt (const RIJNDAEL_context *ctx, - unsigned char *bx, - const unsigned char *ax); +extern unsigned int _gcry_aes_padlock_encrypt (const RIJNDAEL_context *ctx, + unsigned char *bx, + const unsigned char *ax); +extern unsigned int _gcry_aes_padlock_decrypt (const RIJNDAEL_context *ctx, + unsigned char *bx, + const unsigned char *ax); #endif #ifdef USE_ARM_ASM @@ -222,8 +222,8 @@ do_setkey (RIJNDAEL_context *ctx, const byte *key, const unsigned keylen) #ifdef USE_PADLOCK else if (hwfeatures & HWF_PADLOCK_AES && keylen == 128/8) { - ctx->encrypt_fn = do_padlock_encrypt; - ctx->decrypt_fn = do_padlock_decrypt; + ctx->encrypt_fn = _gcry_aes_padlock_encrypt; + ctx->decrypt_fn = _gcry_aes_padlock_decrypt; ctx->use_padlock = 1; memcpy (ctx->padlockkey, key, keylen); } @@ -532,76 +532,6 @@ do_encrypt (const RIJNDAEL_context *ctx, } -/* Encrypt or decrypt one block using the padlock engine. A and B may - be the same. */ -#ifdef USE_PADLOCK -static unsigned int -do_padlock (const RIJNDAEL_context *ctx, unsigned char *bx, - const unsigned char *ax, int decrypt_flag) -{ - /* BX and AX are not necessary correctly aligned. Thus we need to - copy them here. */ - unsigned char a[16] __attribute__ ((aligned (16))); - unsigned char b[16] __attribute__ ((aligned (16))); - unsigned int cword[4] __attribute__ ((aligned (16))); - int blocks; - - /* The control word fields are: - 127:12 11:10 9 8 7 6 5 4 3:0 - RESERVED KSIZE CRYPT INTER KEYGN CIPHR ALIGN DGEST ROUND */ - cword[0] = (ctx->rounds & 15); /* (The mask is just a safeguard.) */ - cword[1] = 0; - cword[2] = 0; - cword[3] = 0; - if (decrypt_flag) - cword[0] |= 0x00000200; - - memcpy (a, ax, 16); - - blocks = 1; /* Init counter for just one block. */ -#ifdef __x86_64__ - asm volatile - ("pushfq\n\t" /* Force key reload. */ - "popfq\n\t" - ".byte 0xf3, 0x0f, 0xa7, 0xc8\n\t" /* REP XCRYPT ECB. */ - : /* No output */ - : "S" (a), "D" (b), "d" (cword), "b" (ctx->padlockkey), "c" (blocks) - : "cc", "memory" - ); -#else - asm volatile - ("pushfl\n\t" /* Force key reload. */ - "popfl\n\t" - "xchg %3, %%ebx\n\t" /* Load key. */ - ".byte 0xf3, 0x0f, 0xa7, 0xc8\n\t" /* REP XCRYPT ECB. */ - "xchg %3, %%ebx\n" /* Restore GOT register. */ - : /* No output */ - : "S" (a), "D" (b), "d" (cword), "r" (ctx->padlockkey), "c" (blocks) - : "cc", "memory" - ); -#endif - - memcpy (bx, b, 16); - - return (48 + 15 /* possible padding for alignment */); -} - -static unsigned int -do_padlock_encrypt (const RIJNDAEL_context *ctx, - unsigned char *bx, const unsigned char *ax) -{ - return do_padlock(ctx, bx, ax, 0); -} - -static unsigned int -do_padlock_decrypt (const RIJNDAEL_context *ctx, - unsigned char *bx, const unsigned char *ax) -{ - return do_padlock(ctx, bx, ax, 1); -} -#endif /*USE_PADLOCK*/ - - static unsigned int rijndael_encrypt (void *context, byte *b, const byte *a) { diff --git a/configure.ac b/configure.ac index 369be25..c979d57 100644 --- a/configure.ac +++ b/configure.ac @@ -1703,6 +1703,9 @@ if test "$found" = "1" ; then x86) # Build with the AES-NI implementation GCRYPT_CIPHERS="$GCRYPT_CIPHERS rijndael-aesni.lo" + + # Build with the Padlock implementation + GCRYPT_CIPHERS="$GCRYPT_CIPHERS rijndael-padlock.lo" ;; esac fi From jussi.kivilinna at iki.fi Mon Dec 1 20:12:41 2014 From: jussi.kivilinna at iki.fi (Jussi Kivilinna) Date: Mon, 01 Dec 2014 21:12:41 +0200 Subject: [PATCH 1/4] rijndael: split AES-NI functions to separate file Message-ID: <20141201191241.29171.92795.stgit@localhost6.localdomain6> * cipher/Makefile.in: Add 'rijndael-aesni.c'. * cipher/rijndael-aesni.c: New. * cipher/rijndael-internal.h: New. * cipher/rijndael.c (MAXKC, MAXROUNDS, BLOCKSIZE, ATTR_ALIGNED_16) (USE_AMD64_ASM, USE_ARM_ASM, USE_PADLOCK, USE_AESNI, RIJNDAEL_context) (keyschenc, keyschdec, padlockkey): Move to 'rijndael-internal.h'. (u128_s, aesni_prepare, aesni_cleanup, aesni_cleanup_2_6) (aesni_do_setkey, do_aesni_enc, do_aesni_dec, do_aesni_enc_vec4) (do_aesni_dec_vec4, do_aesni_cfb, do_aesni_ctr, do_aesni_ctr_4): Move to 'rijndael-aesni.c'. (prepare_decryption, rijndael_encrypt, _gcry_aes_cfb_enc) (_gcry_aes_cbc_enc, _gcry_aes_ctr_enc, rijndael_decrypt) (_gcry_aes_cfb_dec, _gcry_aes_cbc_dec) [USE_AESNI]: Move to functions in 'rijdael-aesni.c'. * configure.ac [mpi_cpu_arch=x86]: Add 'rijndael-aesni.lo'. -- Clean-up rijndael.c before new new hardware acceleration support gets added. Signed-off-by: Jussi Kivilinna --- cipher/Makefile.am | 3 cipher/rijndael-aesni.c | 1288 +++++++++++++++++++++++++++++++++++++++++ cipher/rijndael-internal.h | 118 ++++ cipher/rijndael.c | 1393 ++------------------------------------------ configure.ac | 7 5 files changed, 1478 insertions(+), 1331 deletions(-) create mode 100644 cipher/rijndael-aesni.c create mode 100644 cipher/rijndael-internal.h diff --git a/cipher/Makefile.am b/cipher/Makefile.am index 22018b3..19b3692 100644 --- a/cipher/Makefile.am +++ b/cipher/Makefile.am @@ -74,7 +74,8 @@ gostr3411-94.c \ md4.c \ md5.c \ poly1305-sse2-amd64.S poly1305-avx2-amd64.S poly1305-armv7-neon.S \ -rijndael.c rijndael-tables.h rijndael-amd64.S rijndael-arm.S \ +rijndael.c rijndael-internal.h rijndael-tables.h rijndael-aesni.c \ + rijndael-amd64.S rijndael-arm.S \ rmd160.c \ rsa.c \ salsa20.c salsa20-amd64.S salsa20-armv7-neon.S \ diff --git a/cipher/rijndael-aesni.c b/cipher/rijndael-aesni.c new file mode 100644 index 0000000..15ed4ad --- /dev/null +++ b/cipher/rijndael-aesni.c @@ -0,0 +1,1288 @@ +/* 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" + + +#ifdef USE_AESNI + + +typedef struct u128_s { u32 a, b, c, d; } u128_t; + + +/* 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. */ +#define aesni_prepare() do { } while (0) +#define aesni_cleanup() \ + do { asm volatile ("pxor %%xmm0, %%xmm0\n\t" \ + "pxor %%xmm1, %%xmm1\n" :: ); \ + } while (0) +#define aesni_cleanup_2_6() \ + do { asm volatile ("pxor %%xmm2, %%xmm2\n\t" \ + "pxor %%xmm3, %%xmm3\n" \ + "pxor %%xmm4, %%xmm4\n" \ + "pxor %%xmm5, %%xmm5\n" \ + "pxor %%xmm6, %%xmm6\n":: ); \ + } while (0) + + +void +_gcry_aes_aesni_do_setkey (RIJNDAEL_context *ctx, const byte *key) +{ + aesni_prepare(); + + if (ctx->rounds < 12) + { + /* 128-bit key */ +#define AESKEYGENASSIST_xmm1_xmm2(imm8) \ + ".byte 0x66, 0x0f, 0x3a, 0xdf, 0xd1, " #imm8 " \n\t" +#define AESKEY_EXPAND128 \ + "pshufd $0xff, %%xmm2, %%xmm2\n\t" \ + "movdqa %%xmm1, %%xmm3\n\t" \ + "pslldq $4, %%xmm3\n\t" \ + "pxor %%xmm3, %%xmm1\n\t" \ + "pslldq $4, %%xmm3\n\t" \ + "pxor %%xmm3, %%xmm1\n\t" \ + "pslldq $4, %%xmm3\n\t" \ + "pxor %%xmm3, %%xmm2\n\t" \ + "pxor %%xmm2, %%xmm1\n\t" + + asm volatile ("movdqu (%[key]), %%xmm1\n\t" /* xmm1 := key */ + "movdqa %%xmm1, (%[ksch])\n\t" /* ksch[0] := xmm1 */ + AESKEYGENASSIST_xmm1_xmm2(0x01) + AESKEY_EXPAND128 + "movdqa %%xmm1, 0x10(%[ksch])\n\t" /* ksch[1] := xmm1 */ + AESKEYGENASSIST_xmm1_xmm2(0x02) + AESKEY_EXPAND128 + "movdqa %%xmm1, 0x20(%[ksch])\n\t" /* ksch[2] := xmm1 */ + AESKEYGENASSIST_xmm1_xmm2(0x04) + AESKEY_EXPAND128 + "movdqa %%xmm1, 0x30(%[ksch])\n\t" /* ksch[3] := xmm1 */ + AESKEYGENASSIST_xmm1_xmm2(0x08) + AESKEY_EXPAND128 + "movdqa %%xmm1, 0x40(%[ksch])\n\t" /* ksch[4] := xmm1 */ + AESKEYGENASSIST_xmm1_xmm2(0x10) + AESKEY_EXPAND128 + "movdqa %%xmm1, 0x50(%[ksch])\n\t" /* ksch[5] := xmm1 */ + AESKEYGENASSIST_xmm1_xmm2(0x20) + AESKEY_EXPAND128 + "movdqa %%xmm1, 0x60(%[ksch])\n\t" /* ksch[6] := xmm1 */ + AESKEYGENASSIST_xmm1_xmm2(0x40) + AESKEY_EXPAND128 + "movdqa %%xmm1, 0x70(%[ksch])\n\t" /* ksch[7] := xmm1 */ + AESKEYGENASSIST_xmm1_xmm2(0x80) + AESKEY_EXPAND128 + "movdqa %%xmm1, 0x80(%[ksch])\n\t" /* ksch[8] := xmm1 */ + AESKEYGENASSIST_xmm1_xmm2(0x1b) + AESKEY_EXPAND128 + "movdqa %%xmm1, 0x90(%[ksch])\n\t" /* ksch[9] := xmm1 */ + AESKEYGENASSIST_xmm1_xmm2(0x36) + AESKEY_EXPAND128 + "movdqa %%xmm1, 0xa0(%[ksch])\n\t" /* ksch[10] := xmm1 */ + : + : [key] "r" (key), [ksch] "r" (ctx->keyschenc) + : "cc", "memory" ); +#undef AESKEYGENASSIST_xmm1_xmm2 +#undef AESKEY_EXPAND128 + } + else if (ctx->rounds == 12) + { + /* 192-bit key */ +#define AESKEYGENASSIST_xmm3_xmm2(imm8) \ + ".byte 0x66, 0x0f, 0x3a, 0xdf, 0xd3, " #imm8 " \n\t" +#define AESKEY_EXPAND192 \ + "pshufd $0x55, %%xmm2, %%xmm2\n\t" \ + "movdqu %%xmm1, %%xmm4\n\t" \ + "pslldq $4, %%xmm4\n\t" \ + "pxor %%xmm4, %%xmm1\n\t" \ + "pslldq $4, %%xmm4\n\t" \ + "pxor %%xmm4, %%xmm1\n\t" \ + "pslldq $4, %%xmm4\n\t" \ + "pxor %%xmm4, %%xmm1\n\t" \ + "pxor %%xmm2, %%xmm1\n\t" \ + "pshufd $0xff, %%xmm1, %%xmm2\n\t" \ + "movdqu %%xmm3, %%xmm4\n\t" \ + "pslldq $4, %%xmm4\n\t" \ + "pxor %%xmm4, %%xmm3\n\t" \ + "pxor %%xmm2, %%xmm3\n\t" + + asm volatile ("movdqu (%[key]), %%xmm1\n\t" /* xmm1 := key[0..15] */ + "movq 16(%[key]), %%xmm3\n\t" /* xmm3 := key[16..23] */ + "movdqa %%xmm1, (%[ksch])\n\t" /* ksch[0] := xmm1 */ + "movdqa %%xmm3, %%xmm5\n\t" + + AESKEYGENASSIST_xmm3_xmm2(0x01) + AESKEY_EXPAND192 + "shufpd $0, %%xmm1, %%xmm5\n\t" + "movdqa %%xmm5, 0x10(%[ksch])\n\t" /* ksch[1] := xmm5 */ + "movdqa %%xmm1, %%xmm6\n\t" + "shufpd $1, %%xmm3, %%xmm6\n\t" + "movdqa %%xmm6, 0x20(%[ksch])\n\t" /* ksch[2] := xmm6 */ + AESKEYGENASSIST_xmm3_xmm2(0x02) + AESKEY_EXPAND192 + "movdqa %%xmm1, 0x30(%[ksch])\n\t" /* ksch[3] := xmm1 */ + "movdqa %%xmm3, %%xmm5\n\t" + + AESKEYGENASSIST_xmm3_xmm2(0x04) + AESKEY_EXPAND192 + "shufpd $0, %%xmm1, %%xmm5\n\t" + "movdqa %%xmm5, 0x40(%[ksch])\n\t" /* ksch[4] := xmm5 */ + "movdqa %%xmm1, %%xmm6\n\t" + "shufpd $1, %%xmm3, %%xmm6\n\t" + "movdqa %%xmm6, 0x50(%[ksch])\n\t" /* ksch[5] := xmm6 */ + AESKEYGENASSIST_xmm3_xmm2(0x08) + AESKEY_EXPAND192 + "movdqa %%xmm1, 0x60(%[ksch])\n\t" /* ksch[6] := xmm1 */ + "movdqa %%xmm3, %%xmm5\n\t" + + AESKEYGENASSIST_xmm3_xmm2(0x10) + AESKEY_EXPAND192 + "shufpd $0, %%xmm1, %%xmm5\n\t" + "movdqa %%xmm5, 0x70(%[ksch])\n\t" /* ksch[7] := xmm5 */ + "movdqa %%xmm1, %%xmm6\n\t" + "shufpd $1, %%xmm3, %%xmm6\n\t" + "movdqa %%xmm6, 0x80(%[ksch])\n\t" /* ksch[8] := xmm6 */ + AESKEYGENASSIST_xmm3_xmm2(0x20) + AESKEY_EXPAND192 + "movdqa %%xmm1, 0x90(%[ksch])\n\t" /* ksch[9] := xmm1 */ + "movdqa %%xmm3, %%xmm5\n\t" + + AESKEYGENASSIST_xmm3_xmm2(0x40) + AESKEY_EXPAND192 + "shufpd $0, %%xmm1, %%xmm5\n\t" + "movdqa %%xmm5, 0xa0(%[ksch])\n\t" /* ksch[10] := xmm5 */ + "movdqa %%xmm1, %%xmm6\n\t" + "shufpd $1, %%xmm3, %%xmm6\n\t" + "movdqa %%xmm6, 0xb0(%[ksch])\n\t" /* ksch[11] := xmm6 */ + AESKEYGENASSIST_xmm3_xmm2(0x80) + AESKEY_EXPAND192 + "movdqa %%xmm1, 0xc0(%[ksch])\n\t" /* ksch[12] := xmm1 */ + : + : [key] "r" (key), [ksch] "r" (ctx->keyschenc) + : "cc", "memory" ); +#undef AESKEYGENASSIST_xmm3_xmm2 +#undef AESKEY_EXPAND192 + } + else if (ctx->rounds > 12) + { + /* 256-bit key */ +#define AESKEYGENASSIST_xmm1_xmm2(imm8) \ + ".byte 0x66, 0x0f, 0x3a, 0xdf, 0xd1, " #imm8 " \n\t" +#define AESKEYGENASSIST_xmm3_xmm2(imm8) \ + ".byte 0x66, 0x0f, 0x3a, 0xdf, 0xd3, " #imm8 " \n\t" +#define AESKEY_EXPAND256_A \ + "pshufd $0xff, %%xmm2, %%xmm2\n\t" \ + "movdqa %%xmm1, %%xmm4\n\t" \ + "pslldq $4, %%xmm4\n\t" \ + "pxor %%xmm4, %%xmm1\n\t" \ + "pslldq $4, %%xmm4\n\t" \ + "pxor %%xmm4, %%xmm1\n\t" \ + "pslldq $4, %%xmm4\n\t" \ + "pxor %%xmm4, %%xmm1\n\t" \ + "pxor %%xmm2, %%xmm1\n\t" +#define AESKEY_EXPAND256_B \ + "pshufd $0xaa, %%xmm2, %%xmm2\n\t" \ + "movdqa %%xmm3, %%xmm4\n\t" \ + "pslldq $4, %%xmm4\n\t" \ + "pxor %%xmm4, %%xmm3\n\t" \ + "pslldq $4, %%xmm4\n\t" \ + "pxor %%xmm4, %%xmm3\n\t" \ + "pslldq $4, %%xmm4\n\t" \ + "pxor %%xmm4, %%xmm3\n\t" \ + "pxor %%xmm2, %%xmm3\n\t" + + asm volatile ("movdqu (%[key]), %%xmm1\n\t" /* xmm1 := key[0..15] */ + "movdqu 16(%[key]), %%xmm3\n\t" /* xmm3 := key[16..31] */ + "movdqa %%xmm1, (%[ksch])\n\t" /* ksch[0] := xmm1 */ + "movdqa %%xmm3, 0x10(%[ksch])\n\t" /* ksch[1] := xmm3 */ + + AESKEYGENASSIST_xmm3_xmm2(0x01) + AESKEY_EXPAND256_A + "movdqa %%xmm1, 0x20(%[ksch])\n\t" /* ksch[2] := xmm1 */ + AESKEYGENASSIST_xmm1_xmm2(0x00) + AESKEY_EXPAND256_B + "movdqa %%xmm3, 0x30(%[ksch])\n\t" /* ksch[3] := xmm3 */ + + AESKEYGENASSIST_xmm3_xmm2(0x02) + AESKEY_EXPAND256_A + "movdqa %%xmm1, 0x40(%[ksch])\n\t" /* ksch[4] := xmm1 */ + AESKEYGENASSIST_xmm1_xmm2(0x00) + AESKEY_EXPAND256_B + "movdqa %%xmm3, 0x50(%[ksch])\n\t" /* ksch[5] := xmm3 */ + + AESKEYGENASSIST_xmm3_xmm2(0x04) + AESKEY_EXPAND256_A + "movdqa %%xmm1, 0x60(%[ksch])\n\t" /* ksch[6] := xmm1 */ + AESKEYGENASSIST_xmm1_xmm2(0x00) + AESKEY_EXPAND256_B + "movdqa %%xmm3, 0x70(%[ksch])\n\t" /* ksch[7] := xmm3 */ + + AESKEYGENASSIST_xmm3_xmm2(0x08) + AESKEY_EXPAND256_A + "movdqa %%xmm1, 0x80(%[ksch])\n\t" /* ksch[8] := xmm1 */ + AESKEYGENASSIST_xmm1_xmm2(0x00) + AESKEY_EXPAND256_B + "movdqa %%xmm3, 0x90(%[ksch])\n\t" /* ksch[9] := xmm3 */ + + AESKEYGENASSIST_xmm3_xmm2(0x10) + AESKEY_EXPAND256_A + "movdqa %%xmm1, 0xa0(%[ksch])\n\t" /* ksch[10] := xmm1 */ + AESKEYGENASSIST_xmm1_xmm2(0x00) + AESKEY_EXPAND256_B + "movdqa %%xmm3, 0xb0(%[ksch])\n\t" /* ksch[11] := xmm3 */ + + AESKEYGENASSIST_xmm3_xmm2(0x20) + AESKEY_EXPAND256_A + "movdqa %%xmm1, 0xc0(%[ksch])\n\t" /* ksch[12] := xmm1 */ + AESKEYGENASSIST_xmm1_xmm2(0x00) + AESKEY_EXPAND256_B + "movdqa %%xmm3, 0xd0(%[ksch])\n\t" /* ksch[13] := xmm3 */ + + AESKEYGENASSIST_xmm3_xmm2(0x40) + AESKEY_EXPAND256_A + "movdqa %%xmm1, 0xe0(%[ksch])\n\t" /* ksch[14] := xmm1 */ + + : + : [key] "r" (key), [ksch] "r" (ctx->keyschenc) + : "cc", "memory" ); +#undef AESKEYGENASSIST_xmm1_xmm2 +#undef AESKEYGENASSIST_xmm3_xmm2 +#undef AESKEY_EXPAND256_A +#undef AESKEY_EXPAND256_B + } + + aesni_cleanup(); + aesni_cleanup_2_6(); +} + + +/* Make a decryption key from an encryption key. */ +void +_gcry_aes_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; + + aesni_prepare(); + +#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 + + aesni_cleanup(); +} + + +/* Encrypt one block using the Intel AES-NI instructions. A and B may + be the same. + + Our problem here is that gcc does not allow the "x" constraint for + SSE registers in asm unless you compile with -msse. The common + wisdom is to use a separate file for SSE instructions and build it + separately. This would require a lot of extra build system stuff, + similar to what we do in mpi/ for the asm stuff. What we do + instead is to use standard registers and a bit more of plain asm + which copies the data and key stuff to the SSE registers and later + back. If we decide to implement some block modes with parallelized + AES instructions, it might indeed be better to use plain asm ala + mpi/. */ +static inline void +do_aesni_enc (const RIJNDAEL_context *ctx, 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" + /* Note: For now we relax the alignment requirement for A and B: It + does not make much difference because in many case we would need + to memcpy them to an extra buffer; using the movdqu is much faster + that memcpy and movdqa. For CFB we know that the IV is properly + aligned but that is a special case. We should better implement + CFB direct in asm. */ + asm volatile ("movdqu %[src], %%xmm0\n\t" /* xmm0 := *a */ + "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 + "movdqu %%xmm0, %[dst]\n" + : [dst] "=m" (*b) + : [src] "m" (*a), + [key] "r" (ctx->keyschenc), + [rounds] "r" (ctx->rounds) + : "cc", "memory"); +#undef aesenc_xmm1_xmm0 +#undef aesenclast_xmm1_xmm0 +} + + +static inline void +do_aesni_dec (const RIJNDAEL_context *ctx, unsigned char *b, + const unsigned char *a) +{ +#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 ("movdqu %[src], %%xmm0\n\t" /* xmm0 := *a */ + "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 + "movdqu %%xmm0, %[dst]\n" + : [dst] "=m" (*b) + : [src] "m" (*a), + [key] "r" (ctx->keyschdec), + [rounds] "r" (ctx->rounds) + : "cc", "memory"); +#undef aesdec_xmm1_xmm0 +#undef aesdeclast_xmm1_xmm0 +} + + +/* Encrypt four blocks using the Intel AES-NI instructions. Blocks are input + * and output through SSE registers xmm1 to xmm4. */ +static inline void +do_aesni_enc_vec4 (const RIJNDAEL_context *ctx) +{ +#define aesenc_xmm0_xmm1 ".byte 0x66, 0x0f, 0x38, 0xdc, 0xc8\n\t" +#define aesenc_xmm0_xmm2 ".byte 0x66, 0x0f, 0x38, 0xdc, 0xd0\n\t" +#define aesenc_xmm0_xmm3 ".byte 0x66, 0x0f, 0x38, 0xdc, 0xd8\n\t" +#define aesenc_xmm0_xmm4 ".byte 0x66, 0x0f, 0x38, 0xdc, 0xe0\n\t" +#define aesenclast_xmm0_xmm1 ".byte 0x66, 0x0f, 0x38, 0xdd, 0xc8\n\t" +#define aesenclast_xmm0_xmm2 ".byte 0x66, 0x0f, 0x38, 0xdd, 0xd0\n\t" +#define aesenclast_xmm0_xmm3 ".byte 0x66, 0x0f, 0x38, 0xdd, 0xd8\n\t" +#define aesenclast_xmm0_xmm4 ".byte 0x66, 0x0f, 0x38, 0xdd, 0xe0\n\t" + asm volatile ("movdqa (%[key]), %%xmm0\n\t" + "pxor %%xmm0, %%xmm1\n\t" /* xmm1 ^= key[0] */ + "pxor %%xmm0, %%xmm2\n\t" /* xmm2 ^= key[0] */ + "pxor %%xmm0, %%xmm3\n\t" /* xmm3 ^= key[0] */ + "pxor %%xmm0, %%xmm4\n\t" /* xmm4 ^= key[0] */ + "movdqa 0x10(%[key]), %%xmm0\n\t" + aesenc_xmm0_xmm1 + aesenc_xmm0_xmm2 + aesenc_xmm0_xmm3 + aesenc_xmm0_xmm4 + "movdqa 0x20(%[key]), %%xmm0\n\t" + aesenc_xmm0_xmm1 + aesenc_xmm0_xmm2 + aesenc_xmm0_xmm3 + aesenc_xmm0_xmm4 + "movdqa 0x30(%[key]), %%xmm0\n\t" + aesenc_xmm0_xmm1 + aesenc_xmm0_xmm2 + aesenc_xmm0_xmm3 + aesenc_xmm0_xmm4 + "movdqa 0x40(%[key]), %%xmm0\n\t" + aesenc_xmm0_xmm1 + aesenc_xmm0_xmm2 + aesenc_xmm0_xmm3 + aesenc_xmm0_xmm4 + "movdqa 0x50(%[key]), %%xmm0\n\t" + aesenc_xmm0_xmm1 + aesenc_xmm0_xmm2 + aesenc_xmm0_xmm3 + aesenc_xmm0_xmm4 + "movdqa 0x60(%[key]), %%xmm0\n\t" + aesenc_xmm0_xmm1 + aesenc_xmm0_xmm2 + aesenc_xmm0_xmm3 + aesenc_xmm0_xmm4 + "movdqa 0x70(%[key]), %%xmm0\n\t" + aesenc_xmm0_xmm1 + aesenc_xmm0_xmm2 + aesenc_xmm0_xmm3 + aesenc_xmm0_xmm4 + "movdqa 0x80(%[key]), %%xmm0\n\t" + aesenc_xmm0_xmm1 + aesenc_xmm0_xmm2 + aesenc_xmm0_xmm3 + aesenc_xmm0_xmm4 + "movdqa 0x90(%[key]), %%xmm0\n\t" + aesenc_xmm0_xmm1 + aesenc_xmm0_xmm2 + aesenc_xmm0_xmm3 + aesenc_xmm0_xmm4 + "movdqa 0xa0(%[key]), %%xmm0\n\t" + "cmpl $10, %[rounds]\n\t" + "jz .Ldeclast%=\n\t" + aesenc_xmm0_xmm1 + aesenc_xmm0_xmm2 + aesenc_xmm0_xmm3 + aesenc_xmm0_xmm4 + "movdqa 0xb0(%[key]), %%xmm0\n\t" + aesenc_xmm0_xmm1 + aesenc_xmm0_xmm2 + aesenc_xmm0_xmm3 + aesenc_xmm0_xmm4 + "movdqa 0xc0(%[key]), %%xmm0\n\t" + "cmpl $12, %[rounds]\n\t" + "jz .Ldeclast%=\n\t" + aesenc_xmm0_xmm1 + aesenc_xmm0_xmm2 + aesenc_xmm0_xmm3 + aesenc_xmm0_xmm4 + "movdqa 0xd0(%[key]), %%xmm0\n\t" + aesenc_xmm0_xmm1 + aesenc_xmm0_xmm2 + aesenc_xmm0_xmm3 + aesenc_xmm0_xmm4 + "movdqa 0xe0(%[key]), %%xmm0\n" + + ".Ldeclast%=:\n\t" + aesenclast_xmm0_xmm1 + aesenclast_xmm0_xmm2 + aesenclast_xmm0_xmm3 + aesenclast_xmm0_xmm4 + : /* no output */ + : [key] "r" (ctx->keyschenc), + [rounds] "r" (ctx->rounds) + : "cc", "memory"); +#undef aesenc_xmm0_xmm1 +#undef aesenc_xmm0_xmm2 +#undef aesenc_xmm0_xmm3 +#undef aesenc_xmm0_xmm4 +#undef aesenclast_xmm0_xmm1 +#undef aesenclast_xmm0_xmm2 +#undef aesenclast_xmm0_xmm3 +#undef aesenclast_xmm0_xmm4 +} + + +/* Decrypt four blocks using the Intel AES-NI instructions. Blocks are input + * and output through SSE registers xmm1 to xmm4. */ +static inline void +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 +} + + +/* Perform a CFB encryption or decryption round using the + initialization vector IV and the input block A. Write the result + to the output block B and update IV. IV needs to be 16 byte + aligned. */ +static inline void +do_aesni_cfb (const RIJNDAEL_context *ctx, int decrypt_flag, + unsigned char *iv, 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 %[iv], %%xmm0\n\t" /* xmm0 := IV */ + "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 + "movdqu %[src], %%xmm1\n\t" /* Save input. */ + "pxor %%xmm1, %%xmm0\n\t" /* xmm0 = input ^ IV */ + + "cmpl $1, %[decrypt]\n\t" + "jz .Ldecrypt_%=\n\t" + "movdqa %%xmm0, %[iv]\n\t" /* [encrypt] Store IV. */ + "jmp .Lleave_%=\n" + ".Ldecrypt_%=:\n\t" + "movdqa %%xmm1, %[iv]\n" /* [decrypt] Store IV. */ + ".Lleave_%=:\n\t" + "movdqu %%xmm0, %[dst]\n" /* Store output. */ + : [iv] "+m" (*iv), [dst] "=m" (*b) + : [src] "m" (*a), + [key] "r" (ctx->keyschenc), + [rounds] "g" (ctx->rounds), + [decrypt] "m" (decrypt_flag) + : "cc", "memory"); +#undef aesenc_xmm1_xmm0 +#undef aesenclast_xmm1_xmm0 +} + +/* Perform a CTR encryption round using the counter CTR and the input + block A. Write the result to the output block B and update CTR. + CTR needs to be a 16 byte aligned little-endian value. */ +static void +do_aesni_ctr (const RIJNDAEL_context *ctx, + unsigned char *ctr, unsigned char *b, const unsigned char *a) +{ +#define aesenc_xmm1_xmm0 ".byte 0x66, 0x0f, 0x38, 0xdc, 0xc1\n\t" +#define aesenclast_xmm1_xmm0 ".byte 0x66, 0x0f, 0x38, 0xdd, 0xc1\n\t" + + asm volatile ("movdqa %%xmm5, %%xmm0\n\t" /* xmm0 := CTR (xmm5) */ + "pcmpeqd %%xmm1, %%xmm1\n\t" + "psrldq $8, %%xmm1\n\t" /* xmm1 = -1 */ + + "pshufb %%xmm6, %%xmm5\n\t" + "psubq %%xmm1, %%xmm5\n\t" /* xmm5++ (big endian) */ + + /* detect if 64-bit carry handling is needed */ + "cmpl $0xffffffff, 8(%[ctr])\n\t" + "jne .Lno_carry%=\n\t" + "cmpl $0xffffffff, 12(%[ctr])\n\t" + "jne .Lno_carry%=\n\t" + + "pslldq $8, %%xmm1\n\t" /* move lower 64-bit to high */ + "psubq %%xmm1, %%xmm5\n\t" /* add carry to upper 64bits */ + + ".Lno_carry%=:\n\t" + + "pshufb %%xmm6, %%xmm5\n\t" + "movdqa %%xmm5, (%[ctr])\n\t" /* Update CTR (mem). */ + + "pxor (%[key]), %%xmm0\n\t" /* xmm1 ^= key[0] */ + "movdqa 0x10(%[key]), %%xmm1\n\t" + aesenc_xmm1_xmm0 + "movdqa 0x20(%[key]), %%xmm1\n\t" + aesenc_xmm1_xmm0 + "movdqa 0x30(%[key]), %%xmm1\n\t" + aesenc_xmm1_xmm0 + "movdqa 0x40(%[key]), %%xmm1\n\t" + aesenc_xmm1_xmm0 + "movdqa 0x50(%[key]), %%xmm1\n\t" + aesenc_xmm1_xmm0 + "movdqa 0x60(%[key]), %%xmm1\n\t" + aesenc_xmm1_xmm0 + "movdqa 0x70(%[key]), %%xmm1\n\t" + aesenc_xmm1_xmm0 + "movdqa 0x80(%[key]), %%xmm1\n\t" + aesenc_xmm1_xmm0 + "movdqa 0x90(%[key]), %%xmm1\n\t" + aesenc_xmm1_xmm0 + "movdqa 0xa0(%[key]), %%xmm1\n\t" + "cmpl $10, %[rounds]\n\t" + "jz .Lenclast%=\n\t" + aesenc_xmm1_xmm0 + "movdqa 0xb0(%[key]), %%xmm1\n\t" + aesenc_xmm1_xmm0 + "movdqa 0xc0(%[key]), %%xmm1\n\t" + "cmpl $12, %[rounds]\n\t" + "jz .Lenclast%=\n\t" + aesenc_xmm1_xmm0 + "movdqa 0xd0(%[key]), %%xmm1\n\t" + aesenc_xmm1_xmm0 + "movdqa 0xe0(%[key]), %%xmm1\n" + + ".Lenclast%=:\n\t" + aesenclast_xmm1_xmm0 + "movdqu %[src], %%xmm1\n\t" /* xmm1 := input */ + "pxor %%xmm1, %%xmm0\n\t" /* EncCTR ^= input */ + "movdqu %%xmm0, %[dst]" /* Store EncCTR. */ + + : [dst] "=m" (*b) + : [src] "m" (*a), + [ctr] "r" (ctr), + [key] "r" (ctx->keyschenc), + [rounds] "g" (ctx->rounds) + : "cc", "memory"); +#undef aesenc_xmm1_xmm0 +#undef aesenclast_xmm1_xmm0 +} + + +/* Four blocks at a time variant of do_aesni_ctr. */ +static void +do_aesni_ctr_4 (const RIJNDAEL_context *ctx, + unsigned char *ctr, unsigned char *b, const unsigned char *a) +{ +#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: + esi 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 ("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] */ + "movl %[rounds], %%esi\n\t" + + "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). */ + + "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, %%esi\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, %%esi\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 + + "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. */ + + : + : [ctr] "r" (ctr), + [src] "r" (a), + [dst] "r" (b), + [key] "r" (ctx->keyschenc), + [rounds] "g" (ctx->rounds) + : "%esi", "cc", "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 +} + + +void +_gcry_aes_aesni_encrypt (RIJNDAEL_context *ctx, unsigned char *dst, + const unsigned char *src) +{ + aesni_prepare (); + do_aesni_enc (ctx, dst, src); + aesni_cleanup (); +} + + +void +_gcry_aes_aesni_cfb_enc (RIJNDAEL_context *ctx, unsigned char *outbuf, + const unsigned char *inbuf, unsigned char *iv, + size_t nblocks) +{ + aesni_prepare (); + for ( ;nblocks; nblocks-- ) + { + do_aesni_cfb (ctx, 0, iv, outbuf, inbuf); + outbuf += BLOCKSIZE; + inbuf += BLOCKSIZE; + } + aesni_cleanup (); +} + + +void +_gcry_aes_aesni_cbc_enc (RIJNDAEL_context *ctx, unsigned char *outbuf, + const unsigned char *inbuf, unsigned char *iv, + size_t nblocks, int cbc_mac) +{ + unsigned char *last_iv; + + aesni_prepare (); + + last_iv = iv; + + for ( ;nblocks; nblocks-- ) + { + /* ~35% speed up on Sandy-Bridge when doing xoring and copying with + SSE registers. */ + asm volatile ("movdqu %[iv], %%xmm0\n\t" + "movdqu %[inbuf], %%xmm1\n\t" + "pxor %%xmm0, %%xmm1\n\t" + "movdqu %%xmm1, %[outbuf]\n\t" + : /* No output */ + : [iv] "m" (*last_iv), + [inbuf] "m" (*inbuf), + [outbuf] "m" (*outbuf) + : "memory" ); + + do_aesni_enc (ctx, outbuf, outbuf); + + last_iv = outbuf; + inbuf += BLOCKSIZE; + if (!cbc_mac) + outbuf += BLOCKSIZE; + } + + if (last_iv != iv) + { + asm volatile ("movdqu %[last], %%xmm0\n\t" + "movdqu %%xmm0, %[iv]\n\t" + : /* No output */ + : [last] "m" (*last_iv), + [iv] "m" (*iv) + : "memory" ); + } + + aesni_cleanup (); +} + + +void +_gcry_aes_aesni_ctr_enc (RIJNDAEL_context *ctx, unsigned char *outbuf, + const unsigned char *inbuf, unsigned char *ctr, + 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 (); + + 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"); + + for ( ;nblocks > 3 ; nblocks -= 4 ) + { + do_aesni_ctr_4 (ctx, ctr, outbuf, inbuf); + outbuf += 4*BLOCKSIZE; + inbuf += 4*BLOCKSIZE; + } + for ( ;nblocks; nblocks-- ) + { + do_aesni_ctr (ctx, ctr, outbuf, inbuf); + outbuf += BLOCKSIZE; + inbuf += BLOCKSIZE; + } + aesni_cleanup (); + aesni_cleanup_2_6 (); +} + + +void +_gcry_aes_aesni_decrypt (RIJNDAEL_context *ctx, unsigned char *dst, + const unsigned char *src) +{ + aesni_prepare (); + do_aesni_dec (ctx, dst, src); + aesni_cleanup (); +} + + +void +_gcry_aes_aesni_cfb_dec (RIJNDAEL_context *ctx, unsigned char *outbuf, + const unsigned char *inbuf, unsigned char *iv, + size_t nblocks) +{ + aesni_prepare (); + + /* CFB decryption can be parallelized */ + for ( ;nblocks >= 4; nblocks -= 4) + { + asm volatile + ("movdqu (%[iv]), %%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]), %%xmm0\n\t" /* update IV */ + "movdqu %%xmm0, (%[iv])\n\t" + : /* No output */ + : [inbuf] "r" (inbuf), [iv] "r" (iv) + : "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; + } + + for ( ;nblocks; nblocks-- ) + { + do_aesni_cfb (ctx, 1, iv, outbuf, inbuf); + outbuf += BLOCKSIZE; + inbuf += BLOCKSIZE; + } + aesni_cleanup (); + aesni_cleanup_2_6 (); +} + + +void +_gcry_aes_aesni_cbc_dec (RIJNDAEL_context *ctx, unsigned char *outbuf, + const unsigned char *inbuf, unsigned char *iv, + size_t nblocks) +{ + aesni_prepare (); + + asm volatile + ("movdqu %[iv], %%xmm5\n\t" /* use xmm5 as fast IV storage */ + : /* No output */ + : [iv] "m" (*iv) + : "memory"); + + for ( ;nblocks > 3 ; 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], %%xmm2\n\t" /* use xmm2 as savebuf */ + : /* No output */ + : [inbuf] "m" (*inbuf) + : "memory"); + + /* uses only xmm0 and xmm1 */ + do_aesni_dec (ctx, outbuf, inbuf); + + asm volatile + ("movdqu %[outbuf], %%xmm0\n\t" + "pxor %%xmm5, %%xmm0\n\t" /* xor IV with output */ + "movdqu %%xmm0, %[outbuf]\n\t" + "movdqu %%xmm2, %%xmm5\n\t" /* store savebuf as new IV */ + : /* No output */ + : [outbuf] "m" (*outbuf) + : "memory"); + + outbuf += BLOCKSIZE; + inbuf += BLOCKSIZE; + } + + asm volatile + ("movdqu %%xmm5, %[iv]\n\t" /* store IV */ + : /* No output */ + : [iv] "m" (*iv) + : "memory"); + + aesni_cleanup (); + aesni_cleanup_2_6 (); +} + +#endif /* USE_AESNI */ diff --git a/cipher/rijndael-internal.h b/cipher/rijndael-internal.h new file mode 100644 index 0000000..762ea76 --- /dev/null +++ b/cipher/rijndael-internal.h @@ -0,0 +1,118 @@ +/* Rijndael (AES) for GnuPG + * Copyright (C) 2000, 2001, 2002, 2003, 2007, + * 2008, 2011, 2012 Free Software Foundation, Inc. + * + * This file is part of Libgcrypt. + * + * Libgcrypt is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * Libgcrypt is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, see . + */ + +#ifndef G10_RIJNDAEL_INTERNAL_H +#define G10_RIJNDAEL_INTERNAL_H + +#include "types.h" /* for byte and u32 typedefs */ + + +#define MAXKC (256/32) +#define MAXROUNDS 14 +#define BLOCKSIZE (128/8) + + +/* Helper macro to force alignment to 16 bytes. */ +#ifdef HAVE_GCC_ATTRIBUTE_ALIGNED +# define ATTR_ALIGNED_16 __attribute__ ((aligned (16))) +#else +# define ATTR_ALIGNED_16 +#endif + + +/* USE_AMD64_ASM indicates whether to use AMD64 assembly code. */ +#undef USE_AMD64_ASM +#if defined(__x86_64__) && defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) +# define USE_AMD64_ASM 1 +#endif + +/* USE_ARM_ASM indicates whether to use ARM assembly code. */ +#undef USE_ARM_ASM +#if defined(__ARMEL__) +# ifdef HAVE_COMPATIBLE_GCC_ARM_PLATFORM_AS +# define USE_ARM_ASM 1 +# endif +#endif + +/* USE_PADLOCK indicates whether to compile the padlock specific + code. */ +#undef USE_PADLOCK +#ifdef ENABLE_PADLOCK_SUPPORT +# ifdef HAVE_GCC_ATTRIBUTE_ALIGNED +# if (defined (__i386__) && SIZEOF_UNSIGNED_LONG == 4) || defined(__x86_64__) +# define USE_PADLOCK 1 +# endif +# endif +#endif /*ENABLE_PADLOCK_SUPPORT*/ + +/* USE_AESNI inidicates whether to compile with Intel AES-NI code. We + need the vector-size attribute which seems to be available since + gcc 3. However, to be on the safe side we require at least gcc 4. */ +#undef USE_AESNI +#ifdef ENABLE_AESNI_SUPPORT +# if ((defined (__i386__) && SIZEOF_UNSIGNED_LONG == 4) || defined(__x86_64__)) +# if __GNUC__ >= 4 +# define USE_AESNI 1 +# endif +# endif +#endif /* ENABLE_AESNI_SUPPORT */ + + +/* Our context object. */ +typedef struct +{ + /* The first fields are the keyschedule arrays. This is so that + they are aligned on a 16 byte boundary if using gcc. This + alignment is required for the AES-NI code and a good idea in any + case. The alignment is guaranteed due to the way cipher.c + allocates the space for the context. The PROPERLY_ALIGNED_TYPE + hack is used to force a minimal alignment if not using gcc of if + the alignment requirement is higher that 16 bytes. */ + union + { + PROPERLY_ALIGNED_TYPE dummy; + byte keyschedule[MAXROUNDS+1][4][4]; +#ifdef USE_PADLOCK + /* The key as passed to the padlock engine. It is only used if + the padlock engine is used (USE_PADLOCK, below). */ + unsigned char padlock_key[16] __attribute__ ((aligned (16))); +#endif /*USE_PADLOCK*/ + } u1; + union + { + PROPERLY_ALIGNED_TYPE dummy; + byte keyschedule[MAXROUNDS+1][4][4]; + } u2; + int rounds; /* Key-length-dependent number of rounds. */ + unsigned int decryption_prepared:1; /* The decryption key schedule is available. */ +#ifdef USE_PADLOCK + unsigned int use_padlock:1; /* Padlock shall be used. */ +#endif /*USE_PADLOCK*/ +#ifdef USE_AESNI + unsigned int use_aesni:1; /* AES-NI shall be used. */ +#endif /*USE_AESNI*/ +} RIJNDAEL_context ATTR_ALIGNED_16; + +/* Macros defining alias for the keyschedules. */ +#define keyschenc u1.keyschedule +#define keyschdec u2.keyschedule +#define padlockkey u1.padlock_key + +#endif /* G10_RIJNDAEL_INTERNAL_H */ diff --git a/cipher/rijndael.c b/cipher/rijndael.c index 8019f0a..4a10a6b 100644 --- a/cipher/rijndael.c +++ b/cipher/rijndael.c @@ -47,60 +47,8 @@ #include "cipher.h" #include "bufhelp.h" #include "cipher-selftest.h" +#include "rijndael-internal.h" -#define MAXKC (256/32) -#define MAXROUNDS 14 -#define BLOCKSIZE (128/8) - - -/* Helper macro to force alignment to 16 bytes. */ -#ifdef HAVE_GCC_ATTRIBUTE_ALIGNED -# define ATTR_ALIGNED_16 __attribute__ ((aligned (16))) -#else -# define ATTR_ALIGNED_16 -#endif - - -/* USE_AMD64_ASM indicates whether to use AMD64 assembly code. */ -#undef USE_AMD64_ASM -#if defined(__x86_64__) && defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) -# define USE_AMD64_ASM 1 -#endif - -/* USE_ARM_ASM indicates whether to use ARM assembly code. */ -#undef USE_ARM_ASM -#if defined(__ARMEL__) -# ifdef HAVE_COMPATIBLE_GCC_ARM_PLATFORM_AS -# define USE_ARM_ASM 1 -# endif -#endif - -/* USE_PADLOCK indicates whether to compile the padlock specific - code. */ -#undef USE_PADLOCK -#ifdef ENABLE_PADLOCK_SUPPORT -# ifdef HAVE_GCC_ATTRIBUTE_ALIGNED -# if (defined (__i386__) && SIZEOF_UNSIGNED_LONG == 4) || defined(__x86_64__) -# define USE_PADLOCK 1 -# endif -# endif -#endif /*ENABLE_PADLOCK_SUPPORT*/ - -/* USE_AESNI inidicates whether to compile with Intel AES-NI code. We - need the vector-size attribute which seems to be available since - gcc 3. However, to be on the safe side we require at least gcc 4. */ -#undef USE_AESNI -#ifdef ENABLE_AESNI_SUPPORT -# if ((defined (__i386__) && SIZEOF_UNSIGNED_LONG == 4) || defined(__x86_64__)) -# if __GNUC__ >= 4 -# define USE_AESNI 1 -# endif -# endif -#endif /* ENABLE_AESNI_SUPPORT */ - -#ifdef USE_AESNI - typedef struct u128_s { u32 a, b, c, d; } u128_t; -#endif /*USE_AESNI*/ /* Define an u32 variant for the sake of gcc 4.4's strict aliasing. */ #if __GNUC__ > 4 || ( __GNUC__ == 4 && __GNUC_MINOR__ >= 4 ) @@ -123,6 +71,38 @@ extern void _gcry_aes_amd64_decrypt_block(const void *keysched_dec, int rounds); #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 void _gcry_aes_aesni_encrypt (RIJNDAEL_context *ctx, unsigned char *dst, + const unsigned char *src); +extern void _gcry_aes_aesni_decrypt (RIJNDAEL_context *ctx, unsigned char *dst, + const unsigned char *src); +extern void _gcry_aes_aesni_cfb_enc (RIJNDAEL_context *ctx, + unsigned char *outbuf, + const unsigned char *inbuf, + unsigned char *iv, size_t nblocks); +extern void _gcry_aes_aesni_cbc_enc (RIJNDAEL_context *ctx, + unsigned char *outbuf, + const unsigned char *inbuf, + unsigned char *iv, size_t nblocks, + int cbc_mac); +extern void _gcry_aes_aesni_ctr_enc (RIJNDAEL_context *ctx, + unsigned char *outbuf, + const unsigned char *inbuf, + unsigned char *ctr, size_t nblocks); +extern void _gcry_aes_aesni_cfb_dec (RIJNDAEL_context *ctx, + unsigned char *outbuf, + const unsigned char *inbuf, + unsigned char *iv, size_t nblocks); +extern void _gcry_aes_aesni_cbc_dec (RIJNDAEL_context *ctx, + unsigned char *outbuf, + const unsigned char *inbuf, + unsigned char *iv, size_t nblocks); +#endif + #ifdef USE_ARM_ASM /* ARM assembly implementations of AES */ extern void _gcry_aes_arm_encrypt_block(const void *keysched_enc, @@ -136,326 +116,19 @@ extern void _gcry_aes_arm_decrypt_block(const void *keysched_dec, int rounds); #endif /*USE_ARM_ASM*/ - -/* Our context object. */ -typedef struct -{ - /* The first fields are the keyschedule arrays. This is so that - they are aligned on a 16 byte boundary if using gcc. This - alignment is required for the AES-NI code and a good idea in any - case. The alignment is guaranteed due to the way cipher.c - allocates the space for the context. The PROPERLY_ALIGNED_TYPE - hack is used to force a minimal alignment if not using gcc of if - the alignment requirement is higher that 16 bytes. */ - union - { - PROPERLY_ALIGNED_TYPE dummy; - byte keyschedule[MAXROUNDS+1][4][4]; -#ifdef USE_PADLOCK - /* The key as passed to the padlock engine. It is only used if - the padlock engine is used (USE_PADLOCK, below). */ - unsigned char padlock_key[16] __attribute__ ((aligned (16))); -#endif /*USE_PADLOCK*/ - } u1; - union - { - PROPERLY_ALIGNED_TYPE dummy; - byte keyschedule[MAXROUNDS+1][4][4]; - } u2; - int rounds; /* Key-length-dependent number of rounds. */ - unsigned int decryption_prepared:1; /* The decryption key schedule is available. */ -#ifdef USE_PADLOCK - unsigned int use_padlock:1; /* Padlock shall be used. */ -#endif /*USE_PADLOCK*/ -#ifdef USE_AESNI - unsigned int use_aesni:1; /* AES-NI shall be used. */ -#endif /*USE_AESNI*/ -} RIJNDAEL_context ATTR_ALIGNED_16; - -/* Macros defining alias for the keyschedules. */ -#define keyschenc u1.keyschedule -#define keyschdec u2.keyschedule -#define padlockkey u1.padlock_key - -/* 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 USE_AESNI -# define aesni_prepare() do { } while (0) -# define aesni_cleanup() \ - do { asm volatile ("pxor %%xmm0, %%xmm0\n\t" \ - "pxor %%xmm1, %%xmm1\n" :: ); \ - } while (0) -# define aesni_cleanup_2_6() \ - do { asm volatile ("pxor %%xmm2, %%xmm2\n\t" \ - "pxor %%xmm3, %%xmm3\n" \ - "pxor %%xmm4, %%xmm4\n" \ - "pxor %%xmm5, %%xmm5\n" \ - "pxor %%xmm6, %%xmm6\n":: ); \ - } while (0) -#else -# define aesni_prepare() do { } while (0) -# define aesni_cleanup() do { } while (0) -#endif - /* All the numbers. */ #include "rijndael-tables.h" -/* Function prototypes. */ -#if defined(__i386__) && defined(USE_AESNI) -/* We don't want to inline these functions on i386 to help gcc allocate enough - registers. */ -static void do_aesni_ctr (const RIJNDAEL_context *ctx, unsigned char *ctr, - unsigned char *b, const unsigned char *a) - __attribute__ ((__noinline__)); -static void do_aesni_ctr_4 (const RIJNDAEL_context *ctx, unsigned char *ctr, - unsigned char *b, const unsigned char *a) - __attribute__ ((__noinline__)); -#endif /*USE_AESNI*/ +/* Function prototypes. */ static const char *selftest(void); -#ifdef USE_AESNI -static void -aesni_do_setkey (RIJNDAEL_context *ctx, const byte *key) -{ - aesni_prepare(); - - if (ctx->rounds < 12) - { - /* 128-bit key */ -#define AESKEYGENASSIST_xmm1_xmm2(imm8) \ - ".byte 0x66, 0x0f, 0x3a, 0xdf, 0xd1, " #imm8 " \n\t" -#define AESKEY_EXPAND128 \ - "pshufd $0xff, %%xmm2, %%xmm2\n\t" \ - "movdqa %%xmm1, %%xmm3\n\t" \ - "pslldq $4, %%xmm3\n\t" \ - "pxor %%xmm3, %%xmm1\n\t" \ - "pslldq $4, %%xmm3\n\t" \ - "pxor %%xmm3, %%xmm1\n\t" \ - "pslldq $4, %%xmm3\n\t" \ - "pxor %%xmm3, %%xmm2\n\t" \ - "pxor %%xmm2, %%xmm1\n\t" - - asm volatile ("movdqu (%[key]), %%xmm1\n\t" /* xmm1 := key */ - "movdqa %%xmm1, (%[ksch])\n\t" /* ksch[0] := xmm1 */ - AESKEYGENASSIST_xmm1_xmm2(0x01) - AESKEY_EXPAND128 - "movdqa %%xmm1, 0x10(%[ksch])\n\t" /* ksch[1] := xmm1 */ - AESKEYGENASSIST_xmm1_xmm2(0x02) - AESKEY_EXPAND128 - "movdqa %%xmm1, 0x20(%[ksch])\n\t" /* ksch[2] := xmm1 */ - AESKEYGENASSIST_xmm1_xmm2(0x04) - AESKEY_EXPAND128 - "movdqa %%xmm1, 0x30(%[ksch])\n\t" /* ksch[3] := xmm1 */ - AESKEYGENASSIST_xmm1_xmm2(0x08) - AESKEY_EXPAND128 - "movdqa %%xmm1, 0x40(%[ksch])\n\t" /* ksch[4] := xmm1 */ - AESKEYGENASSIST_xmm1_xmm2(0x10) - AESKEY_EXPAND128 - "movdqa %%xmm1, 0x50(%[ksch])\n\t" /* ksch[5] := xmm1 */ - AESKEYGENASSIST_xmm1_xmm2(0x20) - AESKEY_EXPAND128 - "movdqa %%xmm1, 0x60(%[ksch])\n\t" /* ksch[6] := xmm1 */ - AESKEYGENASSIST_xmm1_xmm2(0x40) - AESKEY_EXPAND128 - "movdqa %%xmm1, 0x70(%[ksch])\n\t" /* ksch[7] := xmm1 */ - AESKEYGENASSIST_xmm1_xmm2(0x80) - AESKEY_EXPAND128 - "movdqa %%xmm1, 0x80(%[ksch])\n\t" /* ksch[8] := xmm1 */ - AESKEYGENASSIST_xmm1_xmm2(0x1b) - AESKEY_EXPAND128 - "movdqa %%xmm1, 0x90(%[ksch])\n\t" /* ksch[9] := xmm1 */ - AESKEYGENASSIST_xmm1_xmm2(0x36) - AESKEY_EXPAND128 - "movdqa %%xmm1, 0xa0(%[ksch])\n\t" /* ksch[10] := xmm1 */ - : - : [key] "r" (key), [ksch] "r" (ctx->keyschenc) - : "cc", "memory" ); -#undef AESKEYGENASSIST_xmm1_xmm2 -#undef AESKEY_EXPAND128 - } - else if (ctx->rounds == 12) - { - /* 192-bit key */ -#define AESKEYGENASSIST_xmm3_xmm2(imm8) \ - ".byte 0x66, 0x0f, 0x3a, 0xdf, 0xd3, " #imm8 " \n\t" -#define AESKEY_EXPAND192 \ - "pshufd $0x55, %%xmm2, %%xmm2\n\t" \ - "movdqu %%xmm1, %%xmm4\n\t" \ - "pslldq $4, %%xmm4\n\t" \ - "pxor %%xmm4, %%xmm1\n\t" \ - "pslldq $4, %%xmm4\n\t" \ - "pxor %%xmm4, %%xmm1\n\t" \ - "pslldq $4, %%xmm4\n\t" \ - "pxor %%xmm4, %%xmm1\n\t" \ - "pxor %%xmm2, %%xmm1\n\t" \ - "pshufd $0xff, %%xmm1, %%xmm2\n\t" \ - "movdqu %%xmm3, %%xmm4\n\t" \ - "pslldq $4, %%xmm4\n\t" \ - "pxor %%xmm4, %%xmm3\n\t" \ - "pxor %%xmm2, %%xmm3\n\t" - - asm volatile ("movdqu (%[key]), %%xmm1\n\t" /* xmm1 := key[0..15] */ - "movq 16(%[key]), %%xmm3\n\t" /* xmm3 := key[16..23] */ - "movdqa %%xmm1, (%[ksch])\n\t" /* ksch[0] := xmm1 */ - "movdqa %%xmm3, %%xmm5\n\t" - - AESKEYGENASSIST_xmm3_xmm2(0x01) - AESKEY_EXPAND192 - "shufpd $0, %%xmm1, %%xmm5\n\t" - "movdqa %%xmm5, 0x10(%[ksch])\n\t" /* ksch[1] := xmm5 */ - "movdqa %%xmm1, %%xmm6\n\t" - "shufpd $1, %%xmm3, %%xmm6\n\t" - "movdqa %%xmm6, 0x20(%[ksch])\n\t" /* ksch[2] := xmm6 */ - AESKEYGENASSIST_xmm3_xmm2(0x02) - AESKEY_EXPAND192 - "movdqa %%xmm1, 0x30(%[ksch])\n\t" /* ksch[3] := xmm1 */ - "movdqa %%xmm3, %%xmm5\n\t" - - AESKEYGENASSIST_xmm3_xmm2(0x04) - AESKEY_EXPAND192 - "shufpd $0, %%xmm1, %%xmm5\n\t" - "movdqa %%xmm5, 0x40(%[ksch])\n\t" /* ksch[4] := xmm5 */ - "movdqa %%xmm1, %%xmm6\n\t" - "shufpd $1, %%xmm3, %%xmm6\n\t" - "movdqa %%xmm6, 0x50(%[ksch])\n\t" /* ksch[5] := xmm6 */ - AESKEYGENASSIST_xmm3_xmm2(0x08) - AESKEY_EXPAND192 - "movdqa %%xmm1, 0x60(%[ksch])\n\t" /* ksch[6] := xmm1 */ - "movdqa %%xmm3, %%xmm5\n\t" - - AESKEYGENASSIST_xmm3_xmm2(0x10) - AESKEY_EXPAND192 - "shufpd $0, %%xmm1, %%xmm5\n\t" - "movdqa %%xmm5, 0x70(%[ksch])\n\t" /* ksch[7] := xmm5 */ - "movdqa %%xmm1, %%xmm6\n\t" - "shufpd $1, %%xmm3, %%xmm6\n\t" - "movdqa %%xmm6, 0x80(%[ksch])\n\t" /* ksch[8] := xmm6 */ - AESKEYGENASSIST_xmm3_xmm2(0x20) - AESKEY_EXPAND192 - "movdqa %%xmm1, 0x90(%[ksch])\n\t" /* ksch[9] := xmm1 */ - "movdqa %%xmm3, %%xmm5\n\t" - - AESKEYGENASSIST_xmm3_xmm2(0x40) - AESKEY_EXPAND192 - "shufpd $0, %%xmm1, %%xmm5\n\t" - "movdqa %%xmm5, 0xa0(%[ksch])\n\t" /* ksch[10] := xmm5 */ - "movdqa %%xmm1, %%xmm6\n\t" - "shufpd $1, %%xmm3, %%xmm6\n\t" - "movdqa %%xmm6, 0xb0(%[ksch])\n\t" /* ksch[11] := xmm6 */ - AESKEYGENASSIST_xmm3_xmm2(0x80) - AESKEY_EXPAND192 - "movdqa %%xmm1, 0xc0(%[ksch])\n\t" /* ksch[12] := xmm1 */ - : - : [key] "r" (key), [ksch] "r" (ctx->keyschenc) - : "cc", "memory" ); -#undef AESKEYGENASSIST_xmm3_xmm2 -#undef AESKEY_EXPAND192 - } - else if (ctx->rounds > 12) - { - /* 256-bit key */ -#define AESKEYGENASSIST_xmm1_xmm2(imm8) \ - ".byte 0x66, 0x0f, 0x3a, 0xdf, 0xd1, " #imm8 " \n\t" -#define AESKEYGENASSIST_xmm3_xmm2(imm8) \ - ".byte 0x66, 0x0f, 0x3a, 0xdf, 0xd3, " #imm8 " \n\t" -#define AESKEY_EXPAND256_A \ - "pshufd $0xff, %%xmm2, %%xmm2\n\t" \ - "movdqa %%xmm1, %%xmm4\n\t" \ - "pslldq $4, %%xmm4\n\t" \ - "pxor %%xmm4, %%xmm1\n\t" \ - "pslldq $4, %%xmm4\n\t" \ - "pxor %%xmm4, %%xmm1\n\t" \ - "pslldq $4, %%xmm4\n\t" \ - "pxor %%xmm4, %%xmm1\n\t" \ - "pxor %%xmm2, %%xmm1\n\t" -#define AESKEY_EXPAND256_B \ - "pshufd $0xaa, %%xmm2, %%xmm2\n\t" \ - "movdqa %%xmm3, %%xmm4\n\t" \ - "pslldq $4, %%xmm4\n\t" \ - "pxor %%xmm4, %%xmm3\n\t" \ - "pslldq $4, %%xmm4\n\t" \ - "pxor %%xmm4, %%xmm3\n\t" \ - "pslldq $4, %%xmm4\n\t" \ - "pxor %%xmm4, %%xmm3\n\t" \ - "pxor %%xmm2, %%xmm3\n\t" - - asm volatile ("movdqu (%[key]), %%xmm1\n\t" /* xmm1 := key[0..15] */ - "movdqu 16(%[key]), %%xmm3\n\t" /* xmm3 := key[16..31] */ - "movdqa %%xmm1, (%[ksch])\n\t" /* ksch[0] := xmm1 */ - "movdqa %%xmm3, 0x10(%[ksch])\n\t" /* ksch[1] := xmm3 */ - - AESKEYGENASSIST_xmm3_xmm2(0x01) - AESKEY_EXPAND256_A - "movdqa %%xmm1, 0x20(%[ksch])\n\t" /* ksch[2] := xmm1 */ - AESKEYGENASSIST_xmm1_xmm2(0x00) - AESKEY_EXPAND256_B - "movdqa %%xmm3, 0x30(%[ksch])\n\t" /* ksch[3] := xmm3 */ - - AESKEYGENASSIST_xmm3_xmm2(0x02) - AESKEY_EXPAND256_A - "movdqa %%xmm1, 0x40(%[ksch])\n\t" /* ksch[4] := xmm1 */ - AESKEYGENASSIST_xmm1_xmm2(0x00) - AESKEY_EXPAND256_B - "movdqa %%xmm3, 0x50(%[ksch])\n\t" /* ksch[5] := xmm3 */ - - AESKEYGENASSIST_xmm3_xmm2(0x04) - AESKEY_EXPAND256_A - "movdqa %%xmm1, 0x60(%[ksch])\n\t" /* ksch[6] := xmm1 */ - AESKEYGENASSIST_xmm1_xmm2(0x00) - AESKEY_EXPAND256_B - "movdqa %%xmm3, 0x70(%[ksch])\n\t" /* ksch[7] := xmm3 */ - - AESKEYGENASSIST_xmm3_xmm2(0x08) - AESKEY_EXPAND256_A - "movdqa %%xmm1, 0x80(%[ksch])\n\t" /* ksch[8] := xmm1 */ - AESKEYGENASSIST_xmm1_xmm2(0x00) - AESKEY_EXPAND256_B - "movdqa %%xmm3, 0x90(%[ksch])\n\t" /* ksch[9] := xmm3 */ - - AESKEYGENASSIST_xmm3_xmm2(0x10) - AESKEY_EXPAND256_A - "movdqa %%xmm1, 0xa0(%[ksch])\n\t" /* ksch[10] := xmm1 */ - AESKEYGENASSIST_xmm1_xmm2(0x00) - AESKEY_EXPAND256_B - "movdqa %%xmm3, 0xb0(%[ksch])\n\t" /* ksch[11] := xmm3 */ - - AESKEYGENASSIST_xmm3_xmm2(0x20) - AESKEY_EXPAND256_A - "movdqa %%xmm1, 0xc0(%[ksch])\n\t" /* ksch[12] := xmm1 */ - AESKEYGENASSIST_xmm1_xmm2(0x00) - AESKEY_EXPAND256_B - "movdqa %%xmm3, 0xd0(%[ksch])\n\t" /* ksch[13] := xmm3 */ - - AESKEYGENASSIST_xmm3_xmm2(0x40) - AESKEY_EXPAND256_A - "movdqa %%xmm1, 0xe0(%[ksch])\n\t" /* ksch[14] := xmm1 */ - - : - : [key] "r" (key), [ksch] "r" (ctx->keyschenc) - : "cc", "memory" ); -#undef AESKEYGENASSIST_xmm1_xmm2 -#undef AESKEYGENASSIST_xmm3_xmm2 -#undef AESKEY_EXPAND256_A -#undef AESKEY_EXPAND256_B - } - - aesni_cleanup(); - aesni_cleanup_2_6(); -} -#endif /*USE_AESNI*/ - - - /* Perform the key setup. */ static gcry_err_code_t do_setkey (RIJNDAEL_context *ctx, const byte *key, const unsigned keylen) @@ -566,7 +239,7 @@ do_setkey (RIJNDAEL_context *ctx, const byte *key, const unsigned keylen) } #ifdef USE_AESNI else if (ctx->use_aesni) - aesni_do_setkey(ctx, key); + _gcry_aes_aesni_do_setkey (ctx, key); #endif else { @@ -678,52 +351,7 @@ prepare_decryption( RIJNDAEL_context *ctx ) #ifdef USE_AESNI if (ctx->use_aesni) { - /* 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; - - aesni_prepare(); - -#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 - - aesni_cleanup(); + _gcry_aes_aesni_prepare_decryption (ctx); } else #endif /*USE_AESNI*/ @@ -951,690 +579,6 @@ do_padlock (const RIJNDAEL_context *ctx, int decrypt_flag, #endif /*USE_PADLOCK*/ -#ifdef USE_AESNI -/* Encrypt one block using the Intel AES-NI instructions. A and B may - be the same. - - Our problem here is that gcc does not allow the "x" constraint for - SSE registers in asm unless you compile with -msse. The common - wisdom is to use a separate file for SSE instructions and build it - separately. This would require a lot of extra build system stuff, - similar to what we do in mpi/ for the asm stuff. What we do - instead is to use standard registers and a bit more of plain asm - which copies the data and key stuff to the SSE registers and later - back. If we decide to implement some block modes with parallelized - AES instructions, it might indeed be better to use plain asm ala - mpi/. */ -static inline void -do_aesni_enc (const RIJNDAEL_context *ctx, 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" - /* Note: For now we relax the alignment requirement for A and B: It - does not make much difference because in many case we would need - to memcpy them to an extra buffer; using the movdqu is much faster - that memcpy and movdqa. For CFB we know that the IV is properly - aligned but that is a special case. We should better implement - CFB direct in asm. */ - asm volatile ("movdqu %[src], %%xmm0\n\t" /* xmm0 := *a */ - "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 - "movdqu %%xmm0, %[dst]\n" - : [dst] "=m" (*b) - : [src] "m" (*a), - [key] "r" (ctx->keyschenc), - [rounds] "r" (ctx->rounds) - : "cc", "memory"); -#undef aesenc_xmm1_xmm0 -#undef aesenclast_xmm1_xmm0 -} - - -static inline void -do_aesni_dec (const RIJNDAEL_context *ctx, unsigned char *b, - const unsigned char *a) -{ -#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 ("movdqu %[src], %%xmm0\n\t" /* xmm0 := *a */ - "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 - "movdqu %%xmm0, %[dst]\n" - : [dst] "=m" (*b) - : [src] "m" (*a), - [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 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 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 -} - - -/* Perform a CFB encryption or decryption round using the - initialization vector IV and the input block A. Write the result - to the output block B and update IV. IV needs to be 16 byte - aligned. */ -static void -do_aesni_cfb (const RIJNDAEL_context *ctx, int decrypt_flag, - unsigned char *iv, 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 %[iv], %%xmm0\n\t" /* xmm0 := IV */ - "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 - "movdqu %[src], %%xmm1\n\t" /* Save input. */ - "pxor %%xmm1, %%xmm0\n\t" /* xmm0 = input ^ IV */ - - "cmpl $1, %[decrypt]\n\t" - "jz .Ldecrypt_%=\n\t" - "movdqa %%xmm0, %[iv]\n\t" /* [encrypt] Store IV. */ - "jmp .Lleave_%=\n" - ".Ldecrypt_%=:\n\t" - "movdqa %%xmm1, %[iv]\n" /* [decrypt] Store IV. */ - ".Lleave_%=:\n\t" - "movdqu %%xmm0, %[dst]\n" /* Store output. */ - : [iv] "+m" (*iv), [dst] "=m" (*b) - : [src] "m" (*a), - [key] "r" (ctx->keyschenc), - [rounds] "g" (ctx->rounds), - [decrypt] "m" (decrypt_flag) - : "cc", "memory"); -#undef aesenc_xmm1_xmm0 -#undef aesenclast_xmm1_xmm0 -} - -/* Perform a CTR encryption round using the counter CTR and the input - block A. Write the result to the output block B and update CTR. - CTR needs to be a 16 byte aligned little-endian value. */ -static void -do_aesni_ctr (const RIJNDAEL_context *ctx, - unsigned char *ctr, unsigned char *b, const unsigned char *a) -{ -#define aesenc_xmm1_xmm0 ".byte 0x66, 0x0f, 0x38, 0xdc, 0xc1\n\t" -#define aesenclast_xmm1_xmm0 ".byte 0x66, 0x0f, 0x38, 0xdd, 0xc1\n\t" - - asm volatile ("movdqa %%xmm5, %%xmm0\n\t" /* xmm0 := CTR (xmm5) */ - "pcmpeqd %%xmm1, %%xmm1\n\t" - "psrldq $8, %%xmm1\n\t" /* xmm1 = -1 */ - - "pshufb %%xmm6, %%xmm5\n\t" - "psubq %%xmm1, %%xmm5\n\t" /* xmm5++ (big endian) */ - - /* detect if 64-bit carry handling is needed */ - "cmpl $0xffffffff, 8(%[ctr])\n\t" - "jne .Lno_carry%=\n\t" - "cmpl $0xffffffff, 12(%[ctr])\n\t" - "jne .Lno_carry%=\n\t" - - "pslldq $8, %%xmm1\n\t" /* move lower 64-bit to high */ - "psubq %%xmm1, %%xmm5\n\t" /* add carry to upper 64bits */ - - ".Lno_carry%=:\n\t" - - "pshufb %%xmm6, %%xmm5\n\t" - "movdqa %%xmm5, (%[ctr])\n\t" /* Update CTR (mem). */ - - "pxor (%[key]), %%xmm0\n\t" /* xmm1 ^= key[0] */ - "movdqa 0x10(%[key]), %%xmm1\n\t" - aesenc_xmm1_xmm0 - "movdqa 0x20(%[key]), %%xmm1\n\t" - aesenc_xmm1_xmm0 - "movdqa 0x30(%[key]), %%xmm1\n\t" - aesenc_xmm1_xmm0 - "movdqa 0x40(%[key]), %%xmm1\n\t" - aesenc_xmm1_xmm0 - "movdqa 0x50(%[key]), %%xmm1\n\t" - aesenc_xmm1_xmm0 - "movdqa 0x60(%[key]), %%xmm1\n\t" - aesenc_xmm1_xmm0 - "movdqa 0x70(%[key]), %%xmm1\n\t" - aesenc_xmm1_xmm0 - "movdqa 0x80(%[key]), %%xmm1\n\t" - aesenc_xmm1_xmm0 - "movdqa 0x90(%[key]), %%xmm1\n\t" - aesenc_xmm1_xmm0 - "movdqa 0xa0(%[key]), %%xmm1\n\t" - "cmpl $10, %[rounds]\n\t" - "jz .Lenclast%=\n\t" - aesenc_xmm1_xmm0 - "movdqa 0xb0(%[key]), %%xmm1\n\t" - aesenc_xmm1_xmm0 - "movdqa 0xc0(%[key]), %%xmm1\n\t" - "cmpl $12, %[rounds]\n\t" - "jz .Lenclast%=\n\t" - aesenc_xmm1_xmm0 - "movdqa 0xd0(%[key]), %%xmm1\n\t" - aesenc_xmm1_xmm0 - "movdqa 0xe0(%[key]), %%xmm1\n" - - ".Lenclast%=:\n\t" - aesenclast_xmm1_xmm0 - "movdqu %[src], %%xmm1\n\t" /* xmm1 := input */ - "pxor %%xmm1, %%xmm0\n\t" /* EncCTR ^= input */ - "movdqu %%xmm0, %[dst]" /* Store EncCTR. */ - - : [dst] "=m" (*b) - : [src] "m" (*a), - [ctr] "r" (ctr), - [key] "r" (ctx->keyschenc), - [rounds] "g" (ctx->rounds) - : "cc", "memory"); -#undef aesenc_xmm1_xmm0 -#undef aesenclast_xmm1_xmm0 -} - - -/* Four blocks at a time variant of do_aesni_ctr. */ -static void -do_aesni_ctr_4 (const RIJNDAEL_context *ctx, - unsigned char *ctr, unsigned char *b, const unsigned char *a) -{ -#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: - esi 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 ("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] */ - "movl %[rounds], %%esi\n\t" - - "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). */ - - "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, %%esi\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, %%esi\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 - - "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. */ - - : - : [ctr] "r" (ctr), - [src] "r" (a), - [dst] "r" (b), - [key] "r" (ctx->keyschenc), - [rounds] "g" (ctx->rounds) - : "%esi", "cc", "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 -} - -#endif /*USE_AESNI*/ - - static unsigned int rijndael_encrypt (void *context, byte *b, const byte *a) { @@ -1653,9 +597,7 @@ rijndael_encrypt (void *context, byte *b, const byte *a) #ifdef USE_AESNI else if (ctx->use_aesni) { - aesni_prepare (); - do_aesni_enc (ctx, b, a); - aesni_cleanup (); + _gcry_aes_aesni_encrypt (ctx, b, a); burn_stack = 0; } #endif /*USE_AESNI*/ @@ -1703,16 +645,8 @@ _gcry_aes_cfb_enc (void *context, unsigned char *iv, #ifdef USE_AESNI else if (ctx->use_aesni) { - aesni_prepare (); - for ( ;nblocks; nblocks-- ) - { - do_aesni_cfb (ctx, 0, iv, outbuf, inbuf); - outbuf += BLOCKSIZE; - inbuf += BLOCKSIZE; - } - aesni_cleanup (); - - burn_depth = 0; /* No stack usage. */ + _gcry_aes_aesni_cfb_enc (ctx, outbuf, inbuf, iv, nblocks); + burn_depth = 0; } #endif /*USE_AESNI*/ else @@ -1747,40 +681,21 @@ _gcry_aes_cbc_enc (void *context, unsigned char *iv, const unsigned char *inbuf = inbuf_arg; unsigned char *last_iv; unsigned int burn_depth = 48 + 2*sizeof(int); -#ifdef USE_AESNI - int use_aesni = ctx->use_aesni; -#endif + if (0) + ; #ifdef USE_AESNI - if (use_aesni) - aesni_prepare (); -#endif /*USE_AESNI*/ - - last_iv = iv; - - for ( ;nblocks; nblocks-- ) + else if (ctx->use_aesni) { - if (0) - ; -#ifdef USE_AESNI - else if (use_aesni) - { - /* ~35% speed up on Sandy-Bridge when doing xoring and copying with - SSE registers. */ - asm volatile ("movdqu %[iv], %%xmm0\n\t" - "movdqu %[inbuf], %%xmm1\n\t" - "pxor %%xmm0, %%xmm1\n\t" - "movdqu %%xmm1, %[outbuf]\n\t" - : /* No output */ - : [iv] "m" (*last_iv), - [inbuf] "m" (*inbuf), - [outbuf] "m" (*outbuf) - : "memory" ); - - do_aesni_enc (ctx, outbuf, outbuf); - } + _gcry_aes_aesni_cbc_enc (ctx, outbuf, inbuf, iv, nblocks, cbc_mac); + burn_depth = 0; + } #endif /*USE_AESNI*/ - else + else + { + last_iv = iv; + + for ( ;nblocks; nblocks-- ) { buf_xor(outbuf, inbuf, last_iv, BLOCKSIZE); @@ -1792,39 +707,17 @@ _gcry_aes_cbc_enc (void *context, unsigned char *iv, #endif /*USE_PADLOCK*/ else do_encrypt (ctx, outbuf, outbuf ); - } - last_iv = outbuf; - inbuf += BLOCKSIZE; - if (!cbc_mac) - outbuf += BLOCKSIZE; - } + last_iv = outbuf; + inbuf += BLOCKSIZE; + if (!cbc_mac) + outbuf += BLOCKSIZE; + } - if (last_iv != iv) - { - if (0) - ; -#ifdef USE_AESNI - else if (use_aesni) - asm volatile ("movdqu %[last], %%xmm0\n\t" - "movdqu %%xmm0, %[iv]\n\t" - : /* No output */ - : [last] "m" (*last_iv), - [iv] "m" (*iv) - : "memory" ); -#endif /*USE_AESNI*/ - else + if (last_iv != iv) buf_cpy (iv, last_iv, BLOCKSIZE); } -#ifdef USE_AESNI - if (use_aesni) - { - aesni_cleanup (); - burn_depth = 0; /* No stack usage. */ - } -#endif /*USE_AESNI*/ - if (burn_depth) _gcry_burn_stack (burn_depth); } @@ -1851,34 +744,8 @@ _gcry_aes_ctr_enc (void *context, unsigned char *ctr, #ifdef USE_AESNI else if (ctx->use_aesni) { - 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 (); - - 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"); - - for ( ;nblocks > 3 ; nblocks -= 4 ) - { - do_aesni_ctr_4 (ctx, ctr, outbuf, inbuf); - outbuf += 4*BLOCKSIZE; - inbuf += 4*BLOCKSIZE; - } - for ( ;nblocks; nblocks-- ) - { - do_aesni_ctr (ctx, ctr, outbuf, inbuf); - outbuf += BLOCKSIZE; - inbuf += BLOCKSIZE; - } - aesni_cleanup (); - aesni_cleanup_2_6 (); - - burn_depth = 0; /* No stack usage. */ + _gcry_aes_aesni_ctr_enc (ctx, outbuf, inbuf, ctr, nblocks); + burn_depth = 0; } #endif /*USE_AESNI*/ else @@ -2076,9 +943,7 @@ rijndael_decrypt (void *context, byte *b, const byte *a) #ifdef USE_AESNI else if (ctx->use_aesni) { - aesni_prepare (); - do_aesni_dec (ctx, b, a); - aesni_cleanup (); + _gcry_aes_aesni_decrypt (ctx, b, a); burn_stack = 0; } #endif /*USE_AESNI*/ @@ -2124,61 +989,8 @@ _gcry_aes_cfb_dec (void *context, unsigned char *iv, #ifdef USE_AESNI else if (ctx->use_aesni) { - aesni_prepare (); - - /* CFB decryption can be parallelized */ - for ( ;nblocks >= 4; nblocks -= 4) - { - asm volatile - ("movdqu (%[iv]), %%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]), %%xmm0\n\t" /* update IV */ - "movdqu %%xmm0, (%[iv])\n\t" - : /* No output */ - : [inbuf] "r" (inbuf), [iv] "r" (iv) - : "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; - } - - for ( ;nblocks; nblocks-- ) - { - do_aesni_cfb (ctx, 1, iv, outbuf, inbuf); - outbuf += BLOCKSIZE; - inbuf += BLOCKSIZE; - } - aesni_cleanup (); - aesni_cleanup_2_6 (); - - burn_depth = 0; /* No stack usage. */ + _gcry_aes_aesni_cfb_dec (ctx, outbuf, inbuf, iv, nblocks); + burn_depth = 0; } #endif /*USE_AESNI*/ else @@ -2218,87 +1030,8 @@ _gcry_aes_cbc_dec (void *context, unsigned char *iv, #ifdef USE_AESNI else if (ctx->use_aesni) { - aesni_prepare (); - - asm volatile - ("movdqu %[iv], %%xmm5\n\t" /* use xmm5 as fast IV storage */ - : /* No output */ - : [iv] "m" (*iv) - : "memory"); - - for ( ;nblocks > 3 ; 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], %%xmm2\n\t" /* use xmm2 as savebuf */ - : /* No output */ - : [inbuf] "m" (*inbuf) - : "memory"); - - /* uses only xmm0 and xmm1 */ - do_aesni_dec (ctx, outbuf, inbuf); - - asm volatile - ("movdqu %[outbuf], %%xmm0\n\t" - "pxor %%xmm5, %%xmm0\n\t" /* xor IV with output */ - "movdqu %%xmm0, %[outbuf]\n\t" - "movdqu %%xmm2, %%xmm5\n\t" /* store savebuf as new IV */ - : /* No output */ - : [outbuf] "m" (*outbuf) - : "memory"); - - outbuf += BLOCKSIZE; - inbuf += BLOCKSIZE; - } - - asm volatile - ("movdqu %%xmm5, %[iv]\n\t" /* store IV */ - : /* No output */ - : [iv] "m" (*iv) - : "memory"); - - aesni_cleanup (); - aesni_cleanup_2_6 (); - - burn_depth = 0; /* No stack usage. */ + _gcry_aes_aesni_cbc_dec (ctx, outbuf, inbuf, iv, nblocks); + burn_depth = 0; } #endif /*USE_AESNI*/ else diff --git a/configure.ac b/configure.ac index a0d5fc9..369be25 100644 --- a/configure.ac +++ b/configure.ac @@ -1698,6 +1698,13 @@ if test "$found" = "1" ; then GCRYPT_CIPHERS="$GCRYPT_CIPHERS rijndael-arm.lo" ;; esac + + case "$mpi_cpu_arch" in + x86) + # Build with the AES-NI implementation + GCRYPT_CIPHERS="$GCRYPT_CIPHERS rijndael-aesni.lo" + ;; + esac fi LIST_MEMBER(twofish, $enabled_ciphers) From jan.bilek at eftlab.co.uk Wed Dec 3 00:02:35 2014 From: jan.bilek at eftlab.co.uk (Jan Bilek) Date: Wed, 03 Dec 2014 09:02:35 +1000 Subject: AES128 in CBC mode decode on longer data [libgcrypt] In-Reply-To: <547CA59A.9080809@iki.fi> References: <5477CB7C.6020507@eftlab.co.uk> <547ADE44.2020907@iki.fi> <547B154D.70802@eftlab.co.uk> <547B1932.30701@eftlab.co.uk> <547C2800.2090606@eftlab.co.uk> <547CA59A.9080809@iki.fi> Message-ID: <547E450B.3000502@eftlab.co.uk> On 02/12/14 03:30, Jussi Kivilinna wrote: > On 01.12.2014 10:34, Jan Bilek wrote: >> Hello Jussi, >> >> We've been able to reproduce all test vectors from https://github.com/Cloudera-Intel-QA-Transition/test-cases/wiki/Diceros-Test-Cases . >> >> All went well except for AES128 decode in CBC mode. This is strange as the same code does very well for AES 192 & 256. >> >> Would you mind if I'll ask you to confirm on following vector? >> >> KEY = 0700d603a1c514e46b6191ba430a3a0c >> IV = aad1583cd91365e3bb2f0c3430d065bb >> PLAINTEXT = 068b25c7bfb1f8bdd4cfc908f69dffc5ddc726a197f0e5f720f730393279be91 >> CIPHERTEXT = c4dc61d9725967a3020104a9738f23868527ce839aab1752fd8bdb95a82c4d00 >> >> Which should be hopefully something like this: >> >> + { GCRY_CIPHER_AES128, >> + "\x07\x00\xd6\x03\xa1\xc5\x14\xe4\x6b\x61\x91\xba\x43\x0a\x3a\x0c", >> + "\xaa\xd1\x58\x3c\xd9\x13\x65\xe3\xbb\x2f\x0c\x34\x30\xd0\x65\xbb", >> + { { "\x06\x8b\x25\xc7\xbf\xb1\xf8\xbd\xd4\xcf\xc9\x08\xf6\x9d\xff\xc5" >> + "\xdd\xc7\x26\xa1\x97\xf0\xe5\xf7\x20\xf7\x30\x39\x32\x79\xbe\x91", >> + 32, >> + "\xc4\xdc\x61\xd9\x72\x59\x67\xa3\x02\x01\x04\xa9\x73\x8f\x23\x86" >> + "\x85\x27\xce\x83\x9a\xab\x17\x52\xfd\x8b\xdb\x95\xa8\x2c\x4d\x00" }, >> + } >> + }, >> >> If you can encode (should do well) and decode the result back. > Yes, I get correct results in tests/basic.c with that test vector. > > -Jussi Thanks Jussi, we'll keep looking. Kind Regards, Jan From mac at mcrowe.com Wed Dec 3 18:57:57 2014 From: mac at mcrowe.com (Mike Crowe) Date: Wed, 3 Dec 2014 17:57:57 +0000 Subject: lock_pool drops capabilities even when running as root Message-ID: <20141203175757.GA21532@mcrowe.com> We're using libgcrypt in an embedded application that runs as root (i.e. UID=EUID=0.) We recently discovered that libgcrypt operations that allocate secure memory caused all the process's capabilities to be dropped causing surprises later when the rest of the application tries to perform privileged operations. We upgraded libgcrypt so we could use gcry_control(GCRYCTL_DISABLE_PRIV_DROP) but this did not help (for reasons that were obvious once I looked more closely.) The culprit would appear to be the code at the start of secmem.c:lock_pool that calls cap_set_proc. Before calling my capabilities are: CapInh: 0000000000000000 CapPrm: 0000001fffffffff CapEff: 0000001fffffffff CapBnd: 0000001fffffffff afterwards they are: CapInh: 0000000000000000 CapPrm: 0000000000004000 CapEff: 0000000000000000 CapBnd: 0000001fffffffff Borrowing the "uid && !geteuid()" check from lower down fixes the problem for me but I suspect that isn't sufficient for all use cases. --- secmem.c~ 2014-08-21 13:50:39.000000000 +0100 +++ secmem.c 2014-12-03 17:55:08.446683419 +0000 @@ -243,6 +243,7 @@ lock_pool (void *p, size_t n) #if defined(USE_CAPABILITIES) && defined(HAVE_MLOCK) int err; + if (uid && ! geteuid ()) { cap_t cap; Thanks. Mike. From wk at gnupg.org Thu Dec 4 09:13:54 2014 From: wk at gnupg.org (Werner Koch) Date: Thu, 04 Dec 2014 09:13:54 +0100 Subject: lock_pool drops capabilities even when running as root In-Reply-To: <20141203175757.GA21532@mcrowe.com> (Mike Crowe's message of "Wed, 3 Dec 2014 17:57:57 +0000") References: <20141203175757.GA21532@mcrowe.com> Message-ID: <87ppbzvnlp.fsf@vigenere.g10code.de> On Wed, 3 Dec 2014 18:57, mac at mcrowe.com said: > We upgraded libgcrypt so we could use > gcry_control(GCRYCTL_DISABLE_PRIV_DROP) but this did not help (for reasons > that were obvious once I looked more closely.) That was the idea. It seems it has not been tested with capabilities. What do you think of this patch to make GCRYCTL_DISABLE_PRIV_DROP work as expected: diff --git a/src/secmem.c b/src/secmem.c index cfea921..4db80a8 100644 --- a/src/secmem.c +++ b/src/secmem.c @@ -245,15 +245,21 @@ lock_pool (void *p, size_t n) { cap_t cap; - cap = cap_from_text ("cap_ipc_lock+ep"); - cap_set_proc (cap); - cap_free (cap); + if (!no_priv_drop) + { + cap = cap_from_text ("cap_ipc_lock+ep"); + cap_set_proc (cap); + cap_free (cap); + } err = no_mlock? 0 : mlock (p, n); if (err && errno) err = errno; - cap = cap_from_text ("cap_ipc_lock+p"); - cap_set_proc (cap); - cap_free(cap); + if (!no_priv_drop) + { + cap = cap_from_text ("cap_ipc_lock+p"); + cap_set_proc (cap); + cap_free(cap); + } } if (err) Salam-Shalom, Werner -- Die Gedanken sind frei. Ausnahmen regelt ein Bundesgesetz. From mac at mcrowe.com Thu Dec 4 12:49:30 2014 From: mac at mcrowe.com (Mike Crowe) Date: Thu, 4 Dec 2014 11:49:30 +0000 Subject: lock_pool drops capabilities even when running as root In-Reply-To: <87ppbzvnlp.fsf@vigenere.g10code.de> References: <20141203175757.GA21532@mcrowe.com> <87ppbzvnlp.fsf@vigenere.g10code.de> Message-ID: <20141204114930.GA2423@mcrowe.com> On Thursday 04 December 2014 at 09:13:54 +0100, Werner Koch wrote: > On Wed, 3 Dec 2014 18:57, mac at mcrowe.com said: > > > We upgraded libgcrypt so we could use > > gcry_control(GCRYCTL_DISABLE_PRIV_DROP) but this did not help (for reasons > > that were obvious once I looked more closely.) > > That was the idea. It seems it has not been tested with capabilities. > What do you think of this patch to make GCRYCTL_DISABLE_PRIV_DROP work > as expected: > > diff --git a/src/secmem.c b/src/secmem.c > index cfea921..4db80a8 100644 > --- a/src/secmem.c > +++ b/src/secmem.c > @@ -245,15 +245,21 @@ lock_pool (void *p, size_t n) > { > cap_t cap; > > - cap = cap_from_text ("cap_ipc_lock+ep"); > - cap_set_proc (cap); > - cap_free (cap); > + if (!no_priv_drop) > + { > + cap = cap_from_text ("cap_ipc_lock+ep"); > + cap_set_proc (cap); > + cap_free (cap); > + } > err = no_mlock? 0 : mlock (p, n); > if (err && errno) > err = errno; > - cap = cap_from_text ("cap_ipc_lock+p"); > - cap_set_proc (cap); > - cap_free(cap); > + if (!no_priv_drop) > + { > + cap = cap_from_text ("cap_ipc_lock+p"); > + cap_set_proc (cap); > + cap_free(cap); > + } > } > > if (err) Hi Werner, Thanks for the reply. It's now clear to me that my patch was wrong because it also disabled the use of mlock. :( I'm reasonably sure that your patch will solve the problem for us if we set CRYCTL_DISABLE_PRIV_DROP but I don't think it is consistent with the behaviour when USE_CAPABILITIES is not defined. In that case when UID==EUID==0 setting GCRYCTL_DISABLE_PRIV_DROP is not required in order to avoid dropping privileges because of the first condition in this code: /* Test whether we are running setuid(0). */ if (uid && ! geteuid ()) { /* Yes, we are. */ if (!no_priv_drop) { /* Check that we really dropped the privs. * Note: setuid(0) should always fail */ if (setuid (uid) || getuid () != geteuid () || !setuid (0)) log_fatal ("failed to reset uid: %s\n", strerror (errno)); } } However, by looking at this code I may have spotted a more serious problem (although it's not one that affects our use case.) Suppose I have an application that is setuid root so that libgcrypt can use mlock. (Presumably that's the intention of the code quoted above.) I compile and test this program against a version of libgcrypt compiled without capabilities support. The program loses privileges correctly as soon as the mlocking is done via the #if defined(HAVE_MLOCK) code in lock_pool since it does not call GCRYCTL_DISABLE_PRIV_DROP. It goes on to allow access to files safe in the knowledge that by that point it is running with the real UID of the user. Someone comes along and upgrades libgcrypt to a version with capabilities support. Now my program will lose all its capabilities but it will continue to run eith EUID==0. All the code that follows for accessing files is now doing so as root! Given this situation I think that: 1. Your patch should not modify capabilities at all if EUID==UID==0 no matter what no_priv_drop contains. 2. The USE_CAPABILITIES code should also drop traditional privileges too in case the application is setuid root (taking care to do so before losing CAP_SETUID.) 3. The code in secmem_init also looks like it needs the same treatment. I can prepare a patch to do this if you agree. But, to be honest, I'm not really sure that a library like libgcrypt should be in the business of changing privileges in this way anyway. Thanks. Mike. From jussi.kivilinna at iki.fi Sat Dec 6 14:22:34 2014 From: jussi.kivilinna at iki.fi (Jussi Kivilinna) Date: Sat, 06 Dec 2014 15:22:34 +0200 Subject: [PATCH] GCM: move Intel PCLMUL accelerated implementation to separate file Message-ID: <20141206132234.18934.33263.stgit@localhost6.localdomain6> * cipher/Makefile.am: Add 'cipher-gcm-intel-pclmul.c'. * cipher/cipher-gcm-intel-pclmul.c: New. * cipher/cipher-gcm.c [GCM_USE_INTEL_PCLMUL] (_gcry_ghash_setup_intel_pclmul, _gcry_ghash_intel_pclmul): New prototypes. [GCM_USE_INTEL_PCLMUL] (gfmul_pclmul, gfmul_pclmul_aggr4): Move to 'cipher-gcm-intel-pclmul.c'. (ghash): Rename to... (ghash_internal): ...this and move GCM_USE_INTEL_PCLMUL part to new function in 'cipher-gcm-intel-pclmul.c'. (setupM): Move GCM_USE_INTEL_PCLMUL part to new function in 'cipher-gcm-intel-pclmul.c'; Add selection of ghash function based on available HW acceleration. (do_ghash_buf): Change use of 'ghash' to 'c->u_mode.gcm.ghash_fn'. * cipher/internal.h (ghash_fn_t): New. (gcry_cipher_handle): Remove 'use_intel_pclmul'; Add 'ghash_fn'. -- Signed-off-by: Jussi Kivilinna --- cipher/Makefile.am | 4 cipher/cipher-gcm-intel-pclmul.c | 395 ++++++++++++++++++++++++++++++++++++++ cipher/cipher-gcm.c | 395 ++------------------------------------ cipher/cipher-internal.h | 13 + 4 files changed, 430 insertions(+), 377 deletions(-) create mode 100644 cipher/cipher-gcm-intel-pclmul.c diff --git a/cipher/Makefile.am b/cipher/Makefile.am index d7e7773..98142ed 100644 --- a/cipher/Makefile.am +++ b/cipher/Makefile.am @@ -40,8 +40,8 @@ libcipher_la_LIBADD = $(GCRYPT_MODULES) libcipher_la_SOURCES = \ cipher.c cipher-internal.h \ cipher-cbc.c cipher-cfb.c cipher-ofb.c cipher-ctr.c cipher-aeswrap.c \ -cipher-ccm.c cipher-cmac.c cipher-gcm.c cipher-poly1305.c \ -cipher-selftest.c cipher-selftest.h \ +cipher-ccm.c cipher-cmac.c cipher-gcm.c cipher-gcm-intel-pclmul.c \ +cipher-poly1305.c cipher-selftest.c cipher-selftest.h \ pubkey.c pubkey-internal.h pubkey-util.c \ md.c \ mac.c mac-internal.h \ diff --git a/cipher/cipher-gcm-intel-pclmul.c b/cipher/cipher-gcm-intel-pclmul.c new file mode 100644 index 0000000..02e7701 --- /dev/null +++ b/cipher/cipher-gcm-intel-pclmul.c @@ -0,0 +1,395 @@ +/* cipher-gcm-intel-pclmul.c - Intel PCLMUL accelerated Galois Counter Mode + * implementation + * Copyright (C) 2013-2014 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" + + +#ifdef GCM_USE_INTEL_PCLMUL + +/* + Intel PCLMUL ghash based on white paper: + "Intel? Carry-Less Multiplication Instruction and its Usage for Computing the + GCM Mode - Rev 2.01"; Shay Gueron, Michael E. Kounavis. + */ +static inline void gfmul_pclmul(void) +{ + /* Input: XMM0 and XMM1, Output: XMM1. Input XMM0 stays unmodified. + Input must be converted to little-endian. + */ + asm volatile (/* gfmul, xmm0 has operator a and xmm1 has operator b. */ + "pshufd $78, %%xmm0, %%xmm2\n\t" + "pshufd $78, %%xmm1, %%xmm4\n\t" + "pxor %%xmm0, %%xmm2\n\t" /* xmm2 holds a0+a1 */ + "pxor %%xmm1, %%xmm4\n\t" /* xmm4 holds b0+b1 */ + + "movdqa %%xmm0, %%xmm3\n\t" + "pclmulqdq $0, %%xmm1, %%xmm3\n\t" /* xmm3 holds a0*b0 */ + "movdqa %%xmm0, %%xmm6\n\t" + "pclmulqdq $17, %%xmm1, %%xmm6\n\t" /* xmm6 holds a1*b1 */ + "movdqa %%xmm3, %%xmm5\n\t" + "pclmulqdq $0, %%xmm2, %%xmm4\n\t" /* xmm4 holds (a0+a1)*(b0+b1) */ + + "pxor %%xmm6, %%xmm5\n\t" /* xmm5 holds a0*b0+a1*b1 */ + "pxor %%xmm5, %%xmm4\n\t" /* xmm4 holds a0*b0+a1*b1+(a0+a1)*(b0+b1) */ + "movdqa %%xmm4, %%xmm5\n\t" + "psrldq $8, %%xmm4\n\t" + "pslldq $8, %%xmm5\n\t" + "pxor %%xmm5, %%xmm3\n\t" + "pxor %%xmm4, %%xmm6\n\t" /* holds the result of the + carry-less multiplication of xmm0 + by xmm1 */ + + /* shift the result by one bit position to the left cope for + the fact that bits are reversed */ + "movdqa %%xmm3, %%xmm4\n\t" + "movdqa %%xmm6, %%xmm5\n\t" + "pslld $1, %%xmm3\n\t" + "pslld $1, %%xmm6\n\t" + "psrld $31, %%xmm4\n\t" + "psrld $31, %%xmm5\n\t" + "movdqa %%xmm4, %%xmm1\n\t" + "pslldq $4, %%xmm5\n\t" + "pslldq $4, %%xmm4\n\t" + "psrldq $12, %%xmm1\n\t" + "por %%xmm4, %%xmm3\n\t" + "por %%xmm5, %%xmm6\n\t" + "por %%xmm6, %%xmm1\n\t" + + /* first phase of the reduction */ + "movdqa %%xmm3, %%xmm6\n\t" + "movdqa %%xmm3, %%xmm7\n\t" + "pslld $31, %%xmm6\n\t" /* packed right shifting << 31 */ + "movdqa %%xmm3, %%xmm5\n\t" + "pslld $30, %%xmm7\n\t" /* packed right shifting shift << 30 */ + "pslld $25, %%xmm5\n\t" /* packed right shifting shift << 25 */ + "pxor %%xmm7, %%xmm6\n\t" /* xor the shifted versions */ + "pxor %%xmm5, %%xmm6\n\t" + "movdqa %%xmm6, %%xmm7\n\t" + "pslldq $12, %%xmm6\n\t" + "psrldq $4, %%xmm7\n\t" + "pxor %%xmm6, %%xmm3\n\t" /* first phase of the reduction + complete */ + + /* second phase of the reduction */ + "movdqa %%xmm3, %%xmm2\n\t" + "movdqa %%xmm3, %%xmm4\n\t" + "psrld $1, %%xmm2\n\t" /* packed left shifting >> 1 */ + "movdqa %%xmm3, %%xmm5\n\t" + "psrld $2, %%xmm4\n\t" /* packed left shifting >> 2 */ + "psrld $7, %%xmm5\n\t" /* packed left shifting >> 7 */ + "pxor %%xmm4, %%xmm2\n\t" /* xor the shifted versions */ + "pxor %%xmm5, %%xmm2\n\t" + "pxor %%xmm7, %%xmm2\n\t" + "pxor %%xmm2, %%xmm3\n\t" + "pxor %%xmm3, %%xmm1\n\t" /* the result is in xmm1 */ + ::: "cc" ); +} + + +#ifdef __x86_64__ +static inline void gfmul_pclmul_aggr4(void) +{ + /* Input: + H?: XMM0 X_i : XMM6 + H?: XMM8 X_(i-1) : XMM3 + H?: XMM9 X_(i-2) : XMM2 + H?: XMM10 X_(i-3)?Y_(i-4): XMM1 + Output: + Y_i: XMM1 + Inputs XMM0 stays unmodified. + Input must be converted to little-endian. + */ + asm volatile (/* perform clmul and merge results... */ + "pshufd $78, %%xmm10, %%xmm11\n\t" + "pshufd $78, %%xmm1, %%xmm12\n\t" + "pxor %%xmm10, %%xmm11\n\t" /* xmm11 holds 4:a0+a1 */ + "pxor %%xmm1, %%xmm12\n\t" /* xmm12 holds 4:b0+b1 */ + + "pshufd $78, %%xmm9, %%xmm13\n\t" + "pshufd $78, %%xmm2, %%xmm14\n\t" + "pxor %%xmm9, %%xmm13\n\t" /* xmm13 holds 3:a0+a1 */ + "pxor %%xmm2, %%xmm14\n\t" /* xmm14 holds 3:b0+b1 */ + + "pshufd $78, %%xmm8, %%xmm5\n\t" + "pshufd $78, %%xmm3, %%xmm15\n\t" + "pxor %%xmm8, %%xmm5\n\t" /* xmm1 holds 2:a0+a1 */ + "pxor %%xmm3, %%xmm15\n\t" /* xmm2 holds 2:b0+b1 */ + + "movdqa %%xmm10, %%xmm4\n\t" + "movdqa %%xmm9, %%xmm7\n\t" + "pclmulqdq $0, %%xmm1, %%xmm4\n\t" /* xmm4 holds 4:a0*b0 */ + "pclmulqdq $0, %%xmm2, %%xmm7\n\t" /* xmm7 holds 3:a0*b0 */ + "pclmulqdq $17, %%xmm10, %%xmm1\n\t" /* xmm1 holds 4:a1*b1 */ + "pclmulqdq $17, %%xmm9, %%xmm2\n\t" /* xmm9 holds 3:a1*b1 */ + "pclmulqdq $0, %%xmm11, %%xmm12\n\t" /* xmm12 holds 4:(a0+a1)*(b0+b1) */ + "pclmulqdq $0, %%xmm13, %%xmm14\n\t" /* xmm14 holds 3:(a0+a1)*(b0+b1) */ + + "pshufd $78, %%xmm0, %%xmm10\n\t" + "pshufd $78, %%xmm6, %%xmm11\n\t" + "pxor %%xmm0, %%xmm10\n\t" /* xmm10 holds 1:a0+a1 */ + "pxor %%xmm6, %%xmm11\n\t" /* xmm11 holds 1:b0+b1 */ + + "pxor %%xmm4, %%xmm7\n\t" /* xmm7 holds 3+4:a0*b0 */ + "pxor %%xmm2, %%xmm1\n\t" /* xmm1 holds 3+4:a1*b1 */ + "pxor %%xmm14, %%xmm12\n\t" /* xmm12 holds 3+4:(a0+a1)*(b0+b1) */ + + "movdqa %%xmm8, %%xmm13\n\t" + "pclmulqdq $0, %%xmm3, %%xmm13\n\t" /* xmm13 holds 2:a0*b0 */ + "pclmulqdq $17, %%xmm8, %%xmm3\n\t" /* xmm3 holds 2:a1*b1 */ + "pclmulqdq $0, %%xmm5, %%xmm15\n\t" /* xmm15 holds 2:(a0+a1)*(b0+b1) */ + + "pxor %%xmm13, %%xmm7\n\t" /* xmm7 holds 2+3+4:a0*b0 */ + "pxor %%xmm3, %%xmm1\n\t" /* xmm1 holds 2+3+4:a1*b1 */ + "pxor %%xmm15, %%xmm12\n\t" /* xmm12 holds 2+3+4:(a0+a1)*(b0+b1) */ + + "movdqa %%xmm0, %%xmm3\n\t" + "pclmulqdq $0, %%xmm6, %%xmm3\n\t" /* xmm3 holds 1:a0*b0 */ + "pclmulqdq $17, %%xmm0, %%xmm6\n\t" /* xmm6 holds 1:a1*b1 */ + "movdqa %%xmm11, %%xmm4\n\t" + "pclmulqdq $0, %%xmm10, %%xmm4\n\t" /* xmm4 holds 1:(a0+a1)*(b0+b1) */ + + "pxor %%xmm7, %%xmm3\n\t" /* xmm3 holds 1+2+3+4:a0*b0 */ + "pxor %%xmm1, %%xmm6\n\t" /* xmm6 holds 1+2+3+4:a1*b1 */ + "pxor %%xmm12, %%xmm4\n\t" /* xmm4 holds 1+2+3+4:(a0+a1)*(b0+b1) */ + + /* aggregated reduction... */ + "movdqa %%xmm3, %%xmm5\n\t" + "pxor %%xmm6, %%xmm5\n\t" /* xmm5 holds a0*b0+a1*b1 */ + "pxor %%xmm5, %%xmm4\n\t" /* xmm4 holds a0*b0+a1*b1+(a0+a1)*(b0+b1) */ + "movdqa %%xmm4, %%xmm5\n\t" + "psrldq $8, %%xmm4\n\t" + "pslldq $8, %%xmm5\n\t" + "pxor %%xmm5, %%xmm3\n\t" + "pxor %%xmm4, %%xmm6\n\t" /* holds the result of the + carry-less multiplication of xmm0 + by xmm1 */ + + /* shift the result by one bit position to the left cope for + the fact that bits are reversed */ + "movdqa %%xmm3, %%xmm4\n\t" + "movdqa %%xmm6, %%xmm5\n\t" + "pslld $1, %%xmm3\n\t" + "pslld $1, %%xmm6\n\t" + "psrld $31, %%xmm4\n\t" + "psrld $31, %%xmm5\n\t" + "movdqa %%xmm4, %%xmm1\n\t" + "pslldq $4, %%xmm5\n\t" + "pslldq $4, %%xmm4\n\t" + "psrldq $12, %%xmm1\n\t" + "por %%xmm4, %%xmm3\n\t" + "por %%xmm5, %%xmm6\n\t" + "por %%xmm6, %%xmm1\n\t" + + /* first phase of the reduction */ + "movdqa %%xmm3, %%xmm6\n\t" + "movdqa %%xmm3, %%xmm7\n\t" + "pslld $31, %%xmm6\n\t" /* packed right shifting << 31 */ + "movdqa %%xmm3, %%xmm5\n\t" + "pslld $30, %%xmm7\n\t" /* packed right shifting shift << 30 */ + "pslld $25, %%xmm5\n\t" /* packed right shifting shift << 25 */ + "pxor %%xmm7, %%xmm6\n\t" /* xor the shifted versions */ + "pxor %%xmm5, %%xmm6\n\t" + "movdqa %%xmm6, %%xmm7\n\t" + "pslldq $12, %%xmm6\n\t" + "psrldq $4, %%xmm7\n\t" + "pxor %%xmm6, %%xmm3\n\t" /* first phase of the reduction + complete */ + + /* second phase of the reduction */ + "movdqa %%xmm3, %%xmm2\n\t" + "movdqa %%xmm3, %%xmm4\n\t" + "psrld $1, %%xmm2\n\t" /* packed left shifting >> 1 */ + "movdqa %%xmm3, %%xmm5\n\t" + "psrld $2, %%xmm4\n\t" /* packed left shifting >> 2 */ + "psrld $7, %%xmm5\n\t" /* packed left shifting >> 7 */ + "pxor %%xmm4, %%xmm2\n\t" /* xor the shifted versions */ + "pxor %%xmm5, %%xmm2\n\t" + "pxor %%xmm7, %%xmm2\n\t" + "pxor %%xmm2, %%xmm3\n\t" + "pxor %%xmm3, %%xmm1\n\t" /* the result is in xmm1 */ + :::"cc"); +} +#endif + + +void +_gcry_ghash_setup_intel_pclmul (gcry_cipher_hd_t c, byte *h) +{ + u64 tmp[2]; + + /* Swap endianness of hsub. */ + tmp[0] = buf_get_be64(c->u_mode.gcm.u_ghash_key.key + 8); + tmp[1] = buf_get_be64(c->u_mode.gcm.u_ghash_key.key + 0); + buf_cpy (c->u_mode.gcm.u_ghash_key.key, tmp, GCRY_GCM_BLOCK_LEN); + +#ifdef __x86_64__ + asm volatile ("movdqu %[h_1], %%xmm0\n\t" + "movdqa %%xmm0, %%xmm1\n\t" + : + : [h_1] "m" (*tmp)); + + gfmul_pclmul (); /* H?H => H? */ + + asm volatile ("movdqu %%xmm1, 0*16(%[h_234])\n\t" + "movdqa %%xmm1, %%xmm8\n\t" + : + : [h_234] "r" (c->u_mode.gcm.gcm_table) + : "memory"); + + gfmul_pclmul (); /* H?H? => H? */ + + asm volatile ("movdqa %%xmm8, %%xmm0\n\t" + "movdqu %%xmm1, 1*16(%[h_234])\n\t" + "movdqa %%xmm8, %%xmm1\n\t" + : + : [h_234] "r" (c->u_mode.gcm.gcm_table) + : "memory"); + + gfmul_pclmul (); /* H??H? => H? */ + + asm volatile ("movdqu %%xmm1, 2*16(%[h_234])\n\t" + : + : [h_234] "r" (c->u_mode.gcm.gcm_table) + : "memory"); + + /* Clear used registers. */ + asm volatile( "pxor %%xmm0, %%xmm0\n\t" + "pxor %%xmm1, %%xmm1\n\t" + "pxor %%xmm2, %%xmm2\n\t" + "pxor %%xmm3, %%xmm3\n\t" + "pxor %%xmm4, %%xmm4\n\t" + "pxor %%xmm5, %%xmm5\n\t" + "pxor %%xmm6, %%xmm6\n\t" + "pxor %%xmm7, %%xmm7\n\t" + "pxor %%xmm8, %%xmm8\n\t" + ::: "cc" ); +#endif + + wipememory (tmp, sizeof(tmp)); +} + + +unsigned int +_gcry_ghash_intel_pclmul (gcry_cipher_hd_t c, byte *result, const byte *buf, + size_t nblocks) +{ + static const unsigned char be_mask[16] __attribute__ ((aligned (16))) = + { 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 }; + const unsigned int blocksize = GCRY_GCM_BLOCK_LEN; + + if (nblocks == 0) + return 0; + + /* Preload hash and H1. */ + asm volatile ("movdqu %[hash], %%xmm1\n\t" + "movdqa %[hsub], %%xmm0\n\t" + "pshufb %[be_mask], %%xmm1\n\t" /* be => le */ + : + : [hash] "m" (*result), [be_mask] "m" (*be_mask), + [hsub] "m" (*c->u_mode.gcm.u_ghash_key.key)); + +#ifdef __x86_64__ + if (nblocks >= 4) + { + do + { + asm volatile ("movdqa %[be_mask], %%xmm4\n\t" + "movdqu 0*16(%[buf]), %%xmm5\n\t" + "movdqu 1*16(%[buf]), %%xmm2\n\t" + "movdqu 2*16(%[buf]), %%xmm3\n\t" + "movdqu 3*16(%[buf]), %%xmm6\n\t" + "pshufb %%xmm4, %%xmm5\n\t" /* be => le */ + + /* Load H2, H3, H4. */ + "movdqu 2*16(%[h_234]), %%xmm10\n\t" + "movdqu 1*16(%[h_234]), %%xmm9\n\t" + "movdqu 0*16(%[h_234]), %%xmm8\n\t" + + "pxor %%xmm5, %%xmm1\n\t" + "pshufb %%xmm4, %%xmm2\n\t" /* be => le */ + "pshufb %%xmm4, %%xmm3\n\t" /* be => le */ + "pshufb %%xmm4, %%xmm6\n\t" /* be => le */ + : + : [buf] "r" (buf), [be_mask] "m" (*be_mask), + [h_234] "r" (c->u_mode.gcm.gcm_table)); + + gfmul_pclmul_aggr4 (); + + buf += 4 * blocksize; + nblocks -= 4; + } + while (nblocks >= 4); + + /* Clear used x86-64/XMM registers. */ + asm volatile( "pxor %%xmm8, %%xmm8\n\t" + "pxor %%xmm9, %%xmm9\n\t" + "pxor %%xmm10, %%xmm10\n\t" + "pxor %%xmm11, %%xmm11\n\t" + "pxor %%xmm12, %%xmm12\n\t" + "pxor %%xmm13, %%xmm13\n\t" + "pxor %%xmm14, %%xmm14\n\t" + "pxor %%xmm15, %%xmm15\n\t" + ::: "cc" ); + } +#endif + + while (nblocks--) + { + asm volatile ("movdqu %[buf], %%xmm2\n\t" + "pshufb %[be_mask], %%xmm2\n\t" /* be => le */ + "pxor %%xmm2, %%xmm1\n\t" + : + : [buf] "m" (*buf), [be_mask] "m" (*be_mask)); + + gfmul_pclmul (); + + buf += blocksize; + } + + /* Store hash. */ + asm volatile ("pshufb %[be_mask], %%xmm1\n\t" /* be => le */ + "movdqu %%xmm1, %[hash]\n\t" + : [hash] "=m" (*result) + : [be_mask] "m" (*be_mask)); + + /* Clear used registers. */ + asm volatile( "pxor %%xmm0, %%xmm0\n\t" + "pxor %%xmm1, %%xmm1\n\t" + "pxor %%xmm2, %%xmm2\n\t" + "pxor %%xmm3, %%xmm3\n\t" + "pxor %%xmm4, %%xmm4\n\t" + "pxor %%xmm5, %%xmm5\n\t" + "pxor %%xmm6, %%xmm6\n\t" + "pxor %%xmm7, %%xmm7\n\t" + ::: "cc" ); + + return 0; +} + +#endif /* GCM_USE_INTEL_PCLMUL */ diff --git a/cipher/cipher-gcm.c b/cipher/cipher-gcm.c index 0534761..f89b81e 100644 --- a/cipher/cipher-gcm.c +++ b/cipher/cipher-gcm.c @@ -29,6 +29,15 @@ #include "bufhelp.h" #include "./cipher-internal.h" + +#ifdef GCM_USE_INTEL_PCLMUL +extern void _gcry_ghash_setup_intel_pclmul (gcry_cipher_hd_t c, byte *h); + +extern unsigned int _gcry_ghash_intel_pclmul (gcry_cipher_hd_t c, byte *result, + const byte *buf, size_t nblocks); +#endif + + #ifdef GCM_USE_TABLES static const u16 gcmR[256] = { 0x0000, 0x01c2, 0x0384, 0x0246, 0x0708, 0x06ca, 0x048c, 0x054e, @@ -348,325 +357,18 @@ do_ghash (unsigned char *hsub, unsigned char *result, const unsigned char *buf) #endif /* !GCM_USE_TABLES */ -#ifdef GCM_USE_INTEL_PCLMUL -/* - Intel PCLMUL ghash based on white paper: - "Intel? Carry-Less Multiplication Instruction and its Usage for Computing the - GCM Mode - Rev 2.01"; Shay Gueron, Michael E. Kounavis. - */ -static inline void gfmul_pclmul(void) -{ - /* Input: XMM0 and XMM1, Output: XMM1. Input XMM0 stays unmodified. - Input must be converted to little-endian. - */ - asm volatile (/* gfmul, xmm0 has operator a and xmm1 has operator b. */ - "pshufd $78, %%xmm0, %%xmm2\n\t" - "pshufd $78, %%xmm1, %%xmm4\n\t" - "pxor %%xmm0, %%xmm2\n\t" /* xmm2 holds a0+a1 */ - "pxor %%xmm1, %%xmm4\n\t" /* xmm4 holds b0+b1 */ - - "movdqa %%xmm0, %%xmm3\n\t" - "pclmulqdq $0, %%xmm1, %%xmm3\n\t" /* xmm3 holds a0*b0 */ - "movdqa %%xmm0, %%xmm6\n\t" - "pclmulqdq $17, %%xmm1, %%xmm6\n\t" /* xmm6 holds a1*b1 */ - "movdqa %%xmm3, %%xmm5\n\t" - "pclmulqdq $0, %%xmm2, %%xmm4\n\t" /* xmm4 holds (a0+a1)*(b0+b1) */ - - "pxor %%xmm6, %%xmm5\n\t" /* xmm5 holds a0*b0+a1*b1 */ - "pxor %%xmm5, %%xmm4\n\t" /* xmm4 holds a0*b0+a1*b1+(a0+a1)*(b0+b1) */ - "movdqa %%xmm4, %%xmm5\n\t" - "psrldq $8, %%xmm4\n\t" - "pslldq $8, %%xmm5\n\t" - "pxor %%xmm5, %%xmm3\n\t" - "pxor %%xmm4, %%xmm6\n\t" /* holds the result of the - carry-less multiplication of xmm0 - by xmm1 */ - - /* shift the result by one bit position to the left cope for - the fact that bits are reversed */ - "movdqa %%xmm3, %%xmm4\n\t" - "movdqa %%xmm6, %%xmm5\n\t" - "pslld $1, %%xmm3\n\t" - "pslld $1, %%xmm6\n\t" - "psrld $31, %%xmm4\n\t" - "psrld $31, %%xmm5\n\t" - "movdqa %%xmm4, %%xmm1\n\t" - "pslldq $4, %%xmm5\n\t" - "pslldq $4, %%xmm4\n\t" - "psrldq $12, %%xmm1\n\t" - "por %%xmm4, %%xmm3\n\t" - "por %%xmm5, %%xmm6\n\t" - "por %%xmm6, %%xmm1\n\t" - - /* first phase of the reduction */ - "movdqa %%xmm3, %%xmm6\n\t" - "movdqa %%xmm3, %%xmm7\n\t" - "pslld $31, %%xmm6\n\t" /* packed right shifting << 31 */ - "movdqa %%xmm3, %%xmm5\n\t" - "pslld $30, %%xmm7\n\t" /* packed right shifting shift << 30 */ - "pslld $25, %%xmm5\n\t" /* packed right shifting shift << 25 */ - "pxor %%xmm7, %%xmm6\n\t" /* xor the shifted versions */ - "pxor %%xmm5, %%xmm6\n\t" - "movdqa %%xmm6, %%xmm7\n\t" - "pslldq $12, %%xmm6\n\t" - "psrldq $4, %%xmm7\n\t" - "pxor %%xmm6, %%xmm3\n\t" /* first phase of the reduction - complete */ - - /* second phase of the reduction */ - "movdqa %%xmm3, %%xmm2\n\t" - "movdqa %%xmm3, %%xmm4\n\t" - "psrld $1, %%xmm2\n\t" /* packed left shifting >> 1 */ - "movdqa %%xmm3, %%xmm5\n\t" - "psrld $2, %%xmm4\n\t" /* packed left shifting >> 2 */ - "psrld $7, %%xmm5\n\t" /* packed left shifting >> 7 */ - "pxor %%xmm4, %%xmm2\n\t" /* xor the shifted versions */ - "pxor %%xmm5, %%xmm2\n\t" - "pxor %%xmm7, %%xmm2\n\t" - "pxor %%xmm2, %%xmm3\n\t" - "pxor %%xmm3, %%xmm1\n\t" /* the result is in xmm1 */ - ::: "cc" ); -} - -#ifdef __x86_64__ -static inline void gfmul_pclmul_aggr4(void) -{ - /* Input: - H?: XMM0 X_i : XMM6 - H?: XMM8 X_(i-1) : XMM3 - H?: XMM9 X_(i-2) : XMM2 - H?: XMM10 X_(i-3)?Y_(i-4): XMM1 - Output: - Y_i: XMM1 - Inputs XMM0 stays unmodified. - Input must be converted to little-endian. - */ - asm volatile (/* perform clmul and merge results... */ - "pshufd $78, %%xmm10, %%xmm11\n\t" - "pshufd $78, %%xmm1, %%xmm12\n\t" - "pxor %%xmm10, %%xmm11\n\t" /* xmm11 holds 4:a0+a1 */ - "pxor %%xmm1, %%xmm12\n\t" /* xmm12 holds 4:b0+b1 */ - - "pshufd $78, %%xmm9, %%xmm13\n\t" - "pshufd $78, %%xmm2, %%xmm14\n\t" - "pxor %%xmm9, %%xmm13\n\t" /* xmm13 holds 3:a0+a1 */ - "pxor %%xmm2, %%xmm14\n\t" /* xmm14 holds 3:b0+b1 */ - - "pshufd $78, %%xmm8, %%xmm5\n\t" - "pshufd $78, %%xmm3, %%xmm15\n\t" - "pxor %%xmm8, %%xmm5\n\t" /* xmm1 holds 2:a0+a1 */ - "pxor %%xmm3, %%xmm15\n\t" /* xmm2 holds 2:b0+b1 */ - - "movdqa %%xmm10, %%xmm4\n\t" - "movdqa %%xmm9, %%xmm7\n\t" - "pclmulqdq $0, %%xmm1, %%xmm4\n\t" /* xmm4 holds 4:a0*b0 */ - "pclmulqdq $0, %%xmm2, %%xmm7\n\t" /* xmm7 holds 3:a0*b0 */ - "pclmulqdq $17, %%xmm10, %%xmm1\n\t" /* xmm1 holds 4:a1*b1 */ - "pclmulqdq $17, %%xmm9, %%xmm2\n\t" /* xmm9 holds 3:a1*b1 */ - "pclmulqdq $0, %%xmm11, %%xmm12\n\t" /* xmm12 holds 4:(a0+a1)*(b0+b1) */ - "pclmulqdq $0, %%xmm13, %%xmm14\n\t" /* xmm14 holds 3:(a0+a1)*(b0+b1) */ - - "pshufd $78, %%xmm0, %%xmm10\n\t" - "pshufd $78, %%xmm6, %%xmm11\n\t" - "pxor %%xmm0, %%xmm10\n\t" /* xmm10 holds 1:a0+a1 */ - "pxor %%xmm6, %%xmm11\n\t" /* xmm11 holds 1:b0+b1 */ - - "pxor %%xmm4, %%xmm7\n\t" /* xmm7 holds 3+4:a0*b0 */ - "pxor %%xmm2, %%xmm1\n\t" /* xmm1 holds 3+4:a1*b1 */ - "pxor %%xmm14, %%xmm12\n\t" /* xmm12 holds 3+4:(a0+a1)*(b0+b1) */ - - "movdqa %%xmm8, %%xmm13\n\t" - "pclmulqdq $0, %%xmm3, %%xmm13\n\t" /* xmm13 holds 2:a0*b0 */ - "pclmulqdq $17, %%xmm8, %%xmm3\n\t" /* xmm3 holds 2:a1*b1 */ - "pclmulqdq $0, %%xmm5, %%xmm15\n\t" /* xmm15 holds 2:(a0+a1)*(b0+b1) */ - - "pxor %%xmm13, %%xmm7\n\t" /* xmm7 holds 2+3+4:a0*b0 */ - "pxor %%xmm3, %%xmm1\n\t" /* xmm1 holds 2+3+4:a1*b1 */ - "pxor %%xmm15, %%xmm12\n\t" /* xmm12 holds 2+3+4:(a0+a1)*(b0+b1) */ - - "movdqa %%xmm0, %%xmm3\n\t" - "pclmulqdq $0, %%xmm6, %%xmm3\n\t" /* xmm3 holds 1:a0*b0 */ - "pclmulqdq $17, %%xmm0, %%xmm6\n\t" /* xmm6 holds 1:a1*b1 */ - "movdqa %%xmm11, %%xmm4\n\t" - "pclmulqdq $0, %%xmm10, %%xmm4\n\t" /* xmm4 holds 1:(a0+a1)*(b0+b1) */ - - "pxor %%xmm7, %%xmm3\n\t" /* xmm3 holds 1+2+3+4:a0*b0 */ - "pxor %%xmm1, %%xmm6\n\t" /* xmm6 holds 1+2+3+4:a1*b1 */ - "pxor %%xmm12, %%xmm4\n\t" /* xmm4 holds 1+2+3+4:(a0+a1)*(b0+b1) */ - - /* aggregated reduction... */ - "movdqa %%xmm3, %%xmm5\n\t" - "pxor %%xmm6, %%xmm5\n\t" /* xmm5 holds a0*b0+a1*b1 */ - "pxor %%xmm5, %%xmm4\n\t" /* xmm4 holds a0*b0+a1*b1+(a0+a1)*(b0+b1) */ - "movdqa %%xmm4, %%xmm5\n\t" - "psrldq $8, %%xmm4\n\t" - "pslldq $8, %%xmm5\n\t" - "pxor %%xmm5, %%xmm3\n\t" - "pxor %%xmm4, %%xmm6\n\t" /* holds the result of the - carry-less multiplication of xmm0 - by xmm1 */ - - /* shift the result by one bit position to the left cope for - the fact that bits are reversed */ - "movdqa %%xmm3, %%xmm4\n\t" - "movdqa %%xmm6, %%xmm5\n\t" - "pslld $1, %%xmm3\n\t" - "pslld $1, %%xmm6\n\t" - "psrld $31, %%xmm4\n\t" - "psrld $31, %%xmm5\n\t" - "movdqa %%xmm4, %%xmm1\n\t" - "pslldq $4, %%xmm5\n\t" - "pslldq $4, %%xmm4\n\t" - "psrldq $12, %%xmm1\n\t" - "por %%xmm4, %%xmm3\n\t" - "por %%xmm5, %%xmm6\n\t" - "por %%xmm6, %%xmm1\n\t" - - /* first phase of the reduction */ - "movdqa %%xmm3, %%xmm6\n\t" - "movdqa %%xmm3, %%xmm7\n\t" - "pslld $31, %%xmm6\n\t" /* packed right shifting << 31 */ - "movdqa %%xmm3, %%xmm5\n\t" - "pslld $30, %%xmm7\n\t" /* packed right shifting shift << 30 */ - "pslld $25, %%xmm5\n\t" /* packed right shifting shift << 25 */ - "pxor %%xmm7, %%xmm6\n\t" /* xor the shifted versions */ - "pxor %%xmm5, %%xmm6\n\t" - "movdqa %%xmm6, %%xmm7\n\t" - "pslldq $12, %%xmm6\n\t" - "psrldq $4, %%xmm7\n\t" - "pxor %%xmm6, %%xmm3\n\t" /* first phase of the reduction - complete */ - - /* second phase of the reduction */ - "movdqa %%xmm3, %%xmm2\n\t" - "movdqa %%xmm3, %%xmm4\n\t" - "psrld $1, %%xmm2\n\t" /* packed left shifting >> 1 */ - "movdqa %%xmm3, %%xmm5\n\t" - "psrld $2, %%xmm4\n\t" /* packed left shifting >> 2 */ - "psrld $7, %%xmm5\n\t" /* packed left shifting >> 7 */ - "pxor %%xmm4, %%xmm2\n\t" /* xor the shifted versions */ - "pxor %%xmm5, %%xmm2\n\t" - "pxor %%xmm7, %%xmm2\n\t" - "pxor %%xmm2, %%xmm3\n\t" - "pxor %%xmm3, %%xmm1\n\t" /* the result is in xmm1 */ - :::"cc"); -} -#endif - -#endif /*GCM_USE_INTEL_PCLMUL*/ - - static unsigned int -ghash (gcry_cipher_hd_t c, byte *result, const byte *buf, - size_t nblocks) +ghash_internal (gcry_cipher_hd_t c, byte *result, const byte *buf, + size_t nblocks) { const unsigned int blocksize = GCRY_GCM_BLOCK_LEN; - unsigned int burn; - - if (nblocks == 0) - return 0; - - if (0) - ; -#ifdef GCM_USE_INTEL_PCLMUL - else if (c->u_mode.gcm.use_intel_pclmul) - { - 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 }; - - /* Preload hash and H1. */ - asm volatile ("movdqu %[hash], %%xmm1\n\t" - "movdqa %[hsub], %%xmm0\n\t" - "pshufb %[be_mask], %%xmm1\n\t" /* be => le */ - : - : [hash] "m" (*result), [be_mask] "m" (*be_mask), - [hsub] "m" (*c->u_mode.gcm.u_ghash_key.key)); - -#ifdef __x86_64__ - if (nblocks >= 4) - { - do - { - asm volatile ("movdqa %[be_mask], %%xmm4\n\t" - "movdqu 0*16(%[buf]), %%xmm5\n\t" - "movdqu 1*16(%[buf]), %%xmm2\n\t" - "movdqu 2*16(%[buf]), %%xmm3\n\t" - "movdqu 3*16(%[buf]), %%xmm6\n\t" - "pshufb %%xmm4, %%xmm5\n\t" /* be => le */ - - /* Load H2, H3, H4. */ - "movdqu 2*16(%[h_234]), %%xmm10\n\t" - "movdqu 1*16(%[h_234]), %%xmm9\n\t" - "movdqu 0*16(%[h_234]), %%xmm8\n\t" - - "pxor %%xmm5, %%xmm1\n\t" - "pshufb %%xmm4, %%xmm2\n\t" /* be => le */ - "pshufb %%xmm4, %%xmm3\n\t" /* be => le */ - "pshufb %%xmm4, %%xmm6\n\t" /* be => le */ - : - : [buf] "r" (buf), [be_mask] "m" (*be_mask), - [h_234] "r" (c->u_mode.gcm.gcm_table)); - - gfmul_pclmul_aggr4 (); - - buf += 4 * blocksize; - nblocks -= 4; - } - while (nblocks >= 4); - - /* Clear used x86-64/XMM registers. */ - asm volatile( "pxor %%xmm8, %%xmm8\n\t" - "pxor %%xmm9, %%xmm9\n\t" - "pxor %%xmm10, %%xmm10\n\t" - "pxor %%xmm11, %%xmm11\n\t" - "pxor %%xmm12, %%xmm12\n\t" - "pxor %%xmm13, %%xmm13\n\t" - "pxor %%xmm14, %%xmm14\n\t" - "pxor %%xmm15, %%xmm15\n\t" - ::: "cc" ); - } -#endif - - while (nblocks--) - { - asm volatile ("movdqu %[buf], %%xmm2\n\t" - "pshufb %[be_mask], %%xmm2\n\t" /* be => le */ - "pxor %%xmm2, %%xmm1\n\t" - : - : [buf] "m" (*buf), [be_mask] "m" (*be_mask)); - - gfmul_pclmul (); - - buf += blocksize; - } + unsigned int burn = 0; - /* Store hash. */ - asm volatile ("pshufb %[be_mask], %%xmm1\n\t" /* be => le */ - "movdqu %%xmm1, %[hash]\n\t" - : [hash] "=m" (*result) - : [be_mask] "m" (*be_mask)); - - /* Clear used registers. */ - asm volatile( "pxor %%xmm0, %%xmm0\n\t" - "pxor %%xmm1, %%xmm1\n\t" - "pxor %%xmm2, %%xmm2\n\t" - "pxor %%xmm3, %%xmm3\n\t" - "pxor %%xmm4, %%xmm4\n\t" - "pxor %%xmm5, %%xmm5\n\t" - "pxor %%xmm6, %%xmm6\n\t" - "pxor %%xmm7, %%xmm7\n\t" - ::: "cc" ); - burn = 0; - } -#endif - else + while (nblocks) { - while (nblocks) - { - burn = GHASH (c, result, buf); - buf += blocksize; - nblocks--; - } + burn = GHASH (c, result, buf); + buf += blocksize; + nblocks--; } return burn + (burn ? 5*sizeof(void*) : 0); @@ -681,63 +383,15 @@ setupM (gcry_cipher_hd_t c, byte *h) #ifdef GCM_USE_INTEL_PCLMUL else if (_gcry_get_hw_features () & HWF_INTEL_PCLMUL) { - u64 tmp[2]; - - c->u_mode.gcm.use_intel_pclmul = 1; - - /* Swap endianness of hsub. */ - tmp[0] = buf_get_be64(c->u_mode.gcm.u_ghash_key.key + 8); - tmp[1] = buf_get_be64(c->u_mode.gcm.u_ghash_key.key + 0); - buf_cpy (c->u_mode.gcm.u_ghash_key.key, tmp, GCRY_GCM_BLOCK_LEN); - -#ifdef __x86_64__ - asm volatile ("movdqu %[h_1], %%xmm0\n\t" - "movdqa %%xmm0, %%xmm1\n\t" - : - : [h_1] "m" (*tmp)); - - gfmul_pclmul (); /* H?H => H? */ - - asm volatile ("movdqu %%xmm1, 0*16(%[h_234])\n\t" - "movdqa %%xmm1, %%xmm8\n\t" - : - : [h_234] "r" (c->u_mode.gcm.gcm_table) - : "memory"); - - gfmul_pclmul (); /* H?H? => H? */ - - asm volatile ("movdqa %%xmm8, %%xmm0\n\t" - "movdqu %%xmm1, 1*16(%[h_234])\n\t" - "movdqa %%xmm8, %%xmm1\n\t" - : - : [h_234] "r" (c->u_mode.gcm.gcm_table) - : "memory"); - - gfmul_pclmul (); /* H??H? => H? */ - - asm volatile ("movdqu %%xmm1, 2*16(%[h_234])\n\t" - : - : [h_234] "r" (c->u_mode.gcm.gcm_table) - : "memory"); - - /* Clear used registers. */ - asm volatile( "pxor %%xmm0, %%xmm0\n\t" - "pxor %%xmm1, %%xmm1\n\t" - "pxor %%xmm2, %%xmm2\n\t" - "pxor %%xmm3, %%xmm3\n\t" - "pxor %%xmm4, %%xmm4\n\t" - "pxor %%xmm5, %%xmm5\n\t" - "pxor %%xmm6, %%xmm6\n\t" - "pxor %%xmm7, %%xmm7\n\t" - "pxor %%xmm8, %%xmm8\n\t" - ::: "cc" ); -#endif - - wipememory (tmp, sizeof(tmp)); + c->u_mode.gcm.ghash_fn = _gcry_ghash_intel_pclmul; + _gcry_ghash_setup_intel_pclmul(c, h); } #endif else - fillM (c, h); + { + c->u_mode.gcm.ghash_fn = ghash_internal; + fillM (c, h); + } } @@ -810,6 +464,7 @@ do_ghash_buf(gcry_cipher_hd_t c, byte *hash, const byte *buf, { unsigned int blocksize = GCRY_GCM_BLOCK_LEN; unsigned int unused = c->u_mode.gcm.mac_unused; + ghash_fn_t ghash_fn = c->u_mode.gcm.ghash_fn; size_t nblocks, n; unsigned int burn = 0; @@ -843,7 +498,7 @@ do_ghash_buf(gcry_cipher_hd_t c, byte *hash, const byte *buf, gcry_assert (unused == blocksize); /* Process one block from macbuf. */ - burn = ghash (c, hash, c->u_mode.gcm.macbuf, 1); + burn = ghash_fn (c, hash, c->u_mode.gcm.macbuf, 1); unused = 0; } @@ -851,7 +506,7 @@ do_ghash_buf(gcry_cipher_hd_t c, byte *hash, const byte *buf, if (nblocks) { - burn = ghash (c, hash, buf, nblocks); + burn = ghash_fn (c, hash, buf, nblocks); buf += blocksize * nblocks; buflen -= blocksize * nblocks; } diff --git a/cipher/cipher-internal.h b/cipher/cipher-internal.h index f6bda66..fef0ecb 100644 --- a/cipher/cipher-internal.h +++ b/cipher/cipher-internal.h @@ -42,7 +42,7 @@ #define GCM_USE_TABLES 1 -/* GCM_USE_INTEL_PCLMUL inidicates whether to compile GCM with Intel PCLMUL +/* 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) @@ -54,6 +54,10 @@ #endif /* GCM_USE_INTEL_PCLMUL */ +typedef unsigned int (*ghash_fn_t) (gcry_cipher_hd_t c, byte *result, + const byte *buf, size_t nblocks); + + /* A VIA processor with the Padlock engine as well as the Intel AES_NI instructions require an alignment of most data on a 16 byte boundary. Because we trick out the compiler while allocating the @@ -188,6 +192,7 @@ struct gcry_cipher_handle 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]; @@ -209,10 +214,8 @@ struct gcry_cipher_handle unsigned char key[MAX_BLOCKSIZE]; } u_ghash_key; -#ifdef GCM_USE_INTEL_PCLMUL - /* Use Intel PCLMUL instructions for accelerated GHASH. */ - unsigned int use_intel_pclmul:1; -#endif + /* GHASH implementation in use. */ + ghash_fn_t ghash_fn; /* Pre-calculated table for GCM. */ #ifdef GCM_USE_TABLES From jussi.kivilinna at iki.fi Sat Dec 6 14:22:53 2014 From: jussi.kivilinna at iki.fi (Jussi Kivilinna) Date: Sat, 06 Dec 2014 15:22:53 +0200 Subject: [PATCH] rijndael: further optimizations for AES-NI accelerated CBC and CFB bulk modes Message-ID: <20141206132253.19071.33395.stgit@localhost6.localdomain6> * cipher/rijndael-aesni.c (do_aesni_enc, do_aesni_dec): Pass input/output through SSE register XMM0. (do_aesni_cfb): Remove. (_gcry_aes_aesni_encrypt, _gcry_aes_aesni_decrypt): Add loading/storing input/output to/from XMM0. (_gcry_aes_aesni_cfb_enc, _gcry_aes_aesni_cbc_enc) (_gcry_aes_aesni_cfb_dec): Update to use renewed 'do_aesni_enc' and move IV loading/storing outside loop. (_gcry_aes_aesni_cbc_dec): Update to use renewed 'do_aesni_dec'. -- CBC encryption speed is improved ~16% on Intel Haswell and CFB encryption ~8%. Signed-off-by: Jussi Kivilinna --- cipher/rijndael-aesni.c | 244 ++++++++++++++++++++--------------------------- 1 file changed, 104 insertions(+), 140 deletions(-) diff --git a/cipher/rijndael-aesni.c b/cipher/rijndael-aesni.c index e6c1051..3c367ce 100644 --- a/cipher/rijndael-aesni.c +++ b/cipher/rijndael-aesni.c @@ -340,33 +340,14 @@ _gcry_aes_aesni_prepare_decryption (RIJNDAEL_context *ctx) } -/* Encrypt one block using the Intel AES-NI instructions. A and B may - be the same. - - Our problem here is that gcc does not allow the "x" constraint for - SSE registers in asm unless you compile with -msse. The common - wisdom is to use a separate file for SSE instructions and build it - separately. This would require a lot of extra build system stuff, - similar to what we do in mpi/ for the asm stuff. What we do - instead is to use standard registers and a bit more of plain asm - which copies the data and key stuff to the SSE registers and later - back. If we decide to implement some block modes with parallelized - AES instructions, it might indeed be better to use plain asm ala - mpi/. */ +/* Encrypt one block using the Intel AES-NI instructions. Block is input + * and output through SSE register xmm0. */ static inline void -do_aesni_enc (const RIJNDAEL_context *ctx, unsigned char *b, - const unsigned char *a) +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" - /* Note: For now we relax the alignment requirement for A and B: It - does not make much difference because in many case we would need - to memcpy them to an extra buffer; using the movdqu is much faster - that memcpy and movdqa. For CFB we know that the IV is properly - aligned but that is a special case. We should better implement - CFB direct in asm. */ - asm volatile ("movdqu %[src], %%xmm0\n\t" /* xmm0 := *a */ - "movdqa (%[key]), %%xmm1\n\t" /* xmm1 := key[0] */ + 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 @@ -402,10 +383,9 @@ do_aesni_enc (const RIJNDAEL_context *ctx, unsigned char *b, ".Lenclast%=:\n\t" aesenclast_xmm1_xmm0 - "movdqu %%xmm0, %[dst]\n" - : [dst] "=m" (*b) - : [src] "m" (*a), - [key] "r" (ctx->keyschenc), + "\n" + : + : [key] "r" (ctx->keyschenc), [rounds] "r" (ctx->rounds) : "cc", "memory"); #undef aesenc_xmm1_xmm0 @@ -413,14 +393,14 @@ do_aesni_enc (const RIJNDAEL_context *ctx, unsigned char *b, } +/* Decrypt one block using the Intel AES-NI instructions. Block is input + * and output through SSE register xmm0. */ static inline void -do_aesni_dec (const RIJNDAEL_context *ctx, unsigned char *b, - const unsigned char *a) +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 ("movdqu %[src], %%xmm0\n\t" /* xmm0 := *a */ - "movdqa (%[key]), %%xmm1\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 @@ -456,10 +436,9 @@ do_aesni_dec (const RIJNDAEL_context *ctx, unsigned char *b, ".Ldeclast%=:\n\t" aesdeclast_xmm1_xmm0 - "movdqu %%xmm0, %[dst]\n" - : [dst] "=m" (*b) - : [src] "m" (*a), - [key] "r" (ctx->keyschdec), + "\n" + : + : [key] "r" (ctx->keyschdec), [rounds] "r" (ctx->rounds) : "cc", "memory"); #undef aesdec_xmm1_xmm0 @@ -685,74 +664,6 @@ do_aesni_dec_vec4 (const RIJNDAEL_context *ctx) } -/* Perform a CFB encryption or decryption round using the - initialization vector IV and the input block A. Write the result - to the output block B and update IV. IV needs to be 16 byte - aligned. */ -static inline void -do_aesni_cfb (const RIJNDAEL_context *ctx, int decrypt_flag, - unsigned char *iv, 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 %[iv], %%xmm0\n\t" /* xmm0 := IV */ - "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 - "movdqu %[src], %%xmm1\n\t" /* Save input. */ - "pxor %%xmm1, %%xmm0\n\t" /* xmm0 = input ^ IV */ - - "cmpl $1, %[decrypt]\n\t" - "jz .Ldecrypt_%=\n\t" - "movdqa %%xmm0, %[iv]\n\t" /* [encrypt] Store IV. */ - "jmp .Lleave_%=\n" - ".Ldecrypt_%=:\n\t" - "movdqa %%xmm1, %[iv]\n" /* [decrypt] Store IV. */ - ".Lleave_%=:\n\t" - "movdqu %%xmm0, %[dst]\n" /* Store output. */ - : [iv] "+m" (*iv), [dst] "=m" (*b) - : [src] "m" (*a), - [key] "r" (ctx->keyschenc), - [rounds] "g" (ctx->rounds), - [decrypt] "m" (decrypt_flag) - : "cc", "memory"); -#undef aesenc_xmm1_xmm0 -#undef aesenclast_xmm1_xmm0 -} - /* 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. */ @@ -1026,7 +937,15 @@ _gcry_aes_aesni_encrypt (const RIJNDAEL_context *ctx, unsigned char *dst, const unsigned char *src) { aesni_prepare (); - do_aesni_enc (ctx, dst, src); + 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; } @@ -1038,12 +957,32 @@ _gcry_aes_aesni_cfb_enc (RIJNDAEL_context *ctx, unsigned char *outbuf, size_t nblocks) { aesni_prepare (); + + asm volatile ("movdqu %[iv], %%xmm0\n\t" + : /* No output */ + : [iv] "m" (*iv) + : "memory" ); + for ( ;nblocks; nblocks-- ) { - do_aesni_cfb (ctx, 0, iv, outbuf, inbuf); + 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 (); } @@ -1053,45 +992,41 @@ _gcry_aes_aesni_cbc_enc (RIJNDAEL_context *ctx, unsigned char *outbuf, const unsigned char *inbuf, unsigned char *iv, size_t nblocks, int cbc_mac) { - unsigned char *last_iv; - aesni_prepare (); - last_iv = iv; + asm volatile ("movdqu %[iv], %%xmm5\n\t" + : /* No output */ + : [iv] "m" (*iv) + : "memory" ); for ( ;nblocks; nblocks-- ) { - /* ~35% speed up on Sandy-Bridge when doing xoring and copying with - SSE registers. */ - asm volatile ("movdqu %[iv], %%xmm0\n\t" - "movdqu %[inbuf], %%xmm1\n\t" - "pxor %%xmm0, %%xmm1\n\t" - "movdqu %%xmm1, %[outbuf]\n\t" + asm volatile ("movdqu %[inbuf], %%xmm0\n\t" + "pxor %%xmm5, %%xmm0\n\t" : /* No output */ - : [iv] "m" (*last_iv), - [inbuf] "m" (*inbuf), - [outbuf] "m" (*outbuf) + : [inbuf] "m" (*inbuf) : "memory" ); - do_aesni_enc (ctx, outbuf, outbuf); + do_aesni_enc (ctx); + + asm volatile ("movdqa %%xmm0, %%xmm5\n\t" + "movdqu %%xmm0, %[outbuf]\n\t" + : [outbuf] "=m" (*outbuf) + : + : "memory" ); - last_iv = outbuf; inbuf += BLOCKSIZE; if (!cbc_mac) outbuf += BLOCKSIZE; } - if (last_iv != iv) - { - asm volatile ("movdqu %[last], %%xmm0\n\t" - "movdqu %%xmm0, %[iv]\n\t" - : /* No output */ - : [last] "m" (*last_iv), - [iv] "m" (*iv) - : "memory" ); - } + asm volatile ("movdqu %%xmm5, %[iv]\n\t" + : [iv] "=m" (*iv) + : + : "memory" ); aesni_cleanup (); + aesni_cleanup_2_6 (); } @@ -1134,7 +1069,15 @@ _gcry_aes_aesni_decrypt (const RIJNDAEL_context *ctx, unsigned char *dst, const unsigned char *src) { aesni_prepare (); - do_aesni_dec (ctx, dst, src); + 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; } @@ -1147,19 +1090,23 @@ _gcry_aes_aesni_cfb_dec (RIJNDAEL_context *ctx, unsigned char *outbuf, { aesni_prepare (); + asm volatile ("movdqu %[iv], %%xmm6\n\t" + : /* No output */ + : [iv] "m" (*iv) + : "memory" ); + /* CFB decryption can be parallelized */ for ( ;nblocks >= 4; nblocks -= 4) { asm volatile - ("movdqu (%[iv]), %%xmm1\n\t" /* load input blocks */ + ("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]), %%xmm0\n\t" /* update IV */ - "movdqu %%xmm0, (%[iv])\n\t" + "movdqu 3*16(%[inbuf]), %%xmm6\n\t" /* update IV */ : /* No output */ - : [inbuf] "r" (inbuf), [iv] "r" (iv) + : [inbuf] "r" (inbuf) : "memory"); do_aesni_enc_vec4 (ctx); @@ -1190,12 +1137,29 @@ _gcry_aes_aesni_cfb_dec (RIJNDAEL_context *ctx, unsigned char *outbuf, inbuf += 4*BLOCKSIZE; } + asm volatile ("movdqu %%xmm6, %%xmm0\n\t" ::: "cc"); + for ( ;nblocks; nblocks-- ) { - do_aesni_cfb (ctx, 1, iv, outbuf, inbuf); + do_aesni_enc (ctx); + + asm volatile ("movdqa %%xmm0, %%xmm6\n\t" + "movdqu %[inbuf], %%xmm0\n\t" + "pxor %%xmm0, %%xmm6\n\t" + "movdqu %%xmm6, %[outbuf]\n\t" + : [outbuf] "=m" (*outbuf) + : [inbuf] "m" (*inbuf) + : "memory" ); + outbuf += BLOCKSIZE; inbuf += BLOCKSIZE; } + + asm volatile ("movdqu %%xmm0, %[iv]\n\t" + : [iv] "=m" (*iv) + : + : "memory" ); + aesni_cleanup (); aesni_cleanup_2_6 (); } @@ -1256,21 +1220,21 @@ _gcry_aes_aesni_cbc_dec (RIJNDAEL_context *ctx, unsigned char *outbuf, for ( ;nblocks; nblocks-- ) { asm volatile - ("movdqu %[inbuf], %%xmm2\n\t" /* use xmm2 as savebuf */ + ("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, outbuf, inbuf); + do_aesni_dec (ctx); asm volatile - ("movdqu %[outbuf], %%xmm0\n\t" - "pxor %%xmm5, %%xmm0\n\t" /* xor IV with output */ + ("pxor %%xmm5, %%xmm0\n\t" /* xor IV with output */ "movdqu %%xmm0, %[outbuf]\n\t" "movdqu %%xmm2, %%xmm5\n\t" /* store savebuf as new IV */ - : /* No output */ - : [outbuf] "m" (*outbuf) + : [outbuf] "=m" (*outbuf) + : : "memory"); outbuf += BLOCKSIZE; From jussi.kivilinna at iki.fi Fri Dec 12 23:52:27 2014 From: jussi.kivilinna at iki.fi (Jussi Kivilinna) Date: Sat, 13 Dec 2014 00:52:27 +0200 Subject: [PATCH] rijndael: use more compact look-up tables and add table prefetching Message-ID: <20141212225227.1465.65893.stgit@localhost6.localdomain6> * cipher/rijndael-internal.h (rijndael_prefetchfn_t): New. (RIJNDAEL_context): Add 'prefetch_enc_fn' and 'prefetch_dec_fn'. * cipher/rijndael-tables.h (S, T1, T2, T3, T4, T5, T6, T7, T8, S5, U1) (U2, U3, U4): Remove. (encT, decT): Add. * cipher/rijndael.c (_gcry_aes_amd64_encrypt_block) (_gcry_aes_amd64_decrypt_block, _gcry_aes_arm_encrypt_block) (_gcry_aes_arm_encrypt_block): Add parameter for passing table pointer to assembly implementation. (prefetch_table, prefetch_enc, prefetch_dec): New. (do_setkey): Setup context prefetch functions depending on selected rijndael implementation; Use new tables for key setup. (prepare_decryption): Use new tables for decryption key setup. (do_encrypt_aligned): Rename to... (do_encrypt_fn): ... to this, change to use new compact tables and make handle unaligned input. (do_encrypt): Remove handling of unaligned input/output; pass table pointer to assembly implementations. (rijndael_encrypt, _gcry_aes_cfb_enc, _gcry_aes_cbc_enc) (_gcry_aes_ctr_enc, _gcry_aes_cfb_dec): Prefetch encryption tables before encryption. (do_decrypt_aligned): Rename to... (do_decrypt_fn): ... to this, change to use new compact tables and make handle unaligned input. (do_decrypt): Remove handling of unaligned input/output; pass table pointer to assembly implementations. (rijndael_decrypt, _gcry_aes_cbc_dec): Prefetch decryption tables before decryption. * cipher/rijndael-amd64.S: Use 2+2 KiB tables for encryption+decryption; remove tables from assembly file. * cipher/rijndael-arm.S: Remove tables from assembly file. -- Patch replaces 4+4 KiB + 256 B look-up tables in generic implementation and 8+8 KiB look-up tables in AMD64 implementation with 2+2 KiB look-up tables from ARM implementation, and adds prefetching of look-up tables. AMD64 assembly is slower than before because of additional rotation instructions. The generic C implementation is new better optimized and actually faster than before. Benchmark results on Intel i5-4570 (64-bit, AMD64 assembly): tests/bench-slope --disable-hwf intel-aesni --cpu-mhz 3600 cipher aes Old: AES | nanosecs/byte mebibytes/sec cycles/byte ECB enc | 2.75 ns/B 346.9 MiB/s 9.90 c/B ECB dec | 2.80 ns/B 341.0 MiB/s 10.07 c/B CBC enc | 3.07 ns/B 310.7 MiB/s 11.05 c/B CBC dec | 2.84 ns/B 336.1 MiB/s 10.22 c/B CFB enc | 3.09 ns/B 308.8 MiB/s 11.12 c/B CFB dec | 2.87 ns/B 331.8 MiB/s 10.35 c/B OFB enc | 2.91 ns/B 327.3 MiB/s 10.49 c/B OFB dec | 2.92 ns/B 326.9 MiB/s 10.50 c/B CTR enc | 3.24 ns/B 294.6 MiB/s 11.66 c/B CTR dec | 3.23 ns/B 295.2 MiB/s 11.63 c/B = New: AES | nanosecs/byte mebibytes/sec cycles/byte ECB enc | 3.99 ns/B 239.2 MiB/s 14.36 c/B ECB dec | 4.04 ns/B 236.3 MiB/s 14.53 c/B CBC enc | 3.65 ns/B 261.6 MiB/s 13.13 c/B CBC dec | 3.46 ns/B 275.7 MiB/s 12.45 c/B CFB enc | 3.67 ns/B 260.2 MiB/s 13.19 c/B CFB dec | 3.62 ns/B 263.2 MiB/s 13.04 c/B OFB enc | 4.38 ns/B 217.5 MiB/s 15.78 c/B OFB dec | 4.13 ns/B 231.1 MiB/s 14.86 c/B CTR enc | 3.79 ns/B 251.9 MiB/s 13.63 c/B CTR dec | 3.79 ns/B 251.9 MiB/s 13.63 c/B Benchmark on Intel i5-4570 (32-bit mingw, generic C): tests/bench-slope.exe --disable-hwf intel-aesni --cpu-mhz 3600 cipher aes Old: AES | nanosecs/byte mebibytes/sec cycles/byte ECB enc | 5.36 ns/B 178.0 MiB/s 19.29 c/B ECB dec | 5.18 ns/B 184.0 MiB/s 18.66 c/B CBC enc | 5.52 ns/B 172.7 MiB/s 19.88 c/B CBC dec | 5.26 ns/B 181.2 MiB/s 18.95 c/B CFB enc | 5.55 ns/B 171.9 MiB/s 19.98 c/B CFB dec | 5.55 ns/B 171.9 MiB/s 19.97 c/B OFB enc | 5.61 ns/B 170.0 MiB/s 20.20 c/B OFB dec | 5.62 ns/B 169.7 MiB/s 20.24 c/B CTR enc | 5.58 ns/B 171.0 MiB/s 20.08 c/B CTR dec | 5.58 ns/B 170.8 MiB/s 20.10 c/B CCM enc | 11.09 ns/B 85.96 MiB/s 39.94 c/B CCM dec | 11.09 ns/B 85.96 MiB/s 39.94 c/B New: AES | nanosecs/byte mebibytes/sec cycles/byte ECB enc | 4.80 ns/B 198.7 MiB/s 17.28 c/B ECB dec | 4.85 ns/B 196.8 MiB/s 17.45 c/B CBC enc | 4.27 ns/B 223.3 MiB/s 15.38 c/B CBC dec | 4.32 ns/B 220.8 MiB/s 15.55 c/B CFB enc | 4.34 ns/B 219.9 MiB/s 15.61 c/B CFB dec | 4.29 ns/B 222.2 MiB/s 15.45 c/B OFB enc | 5.03 ns/B 189.6 MiB/s 18.11 c/B OFB dec | 5.05 ns/B 188.7 MiB/s 18.19 c/B CTR enc | 4.31 ns/B 221.2 MiB/s 15.52 c/B CTR dec | 4.31 ns/B 221.1 MiB/s 15.53 c/B Signed-off-by: Jussi Kivilinna --- cipher/rijndael-amd64.S | 1211 ++-------------------------- cipher/rijndael-arm.S | 295 ------- cipher/rijndael-internal.h | 3 cipher/rijndael-tables.h | 1909 ++++++-------------------------------------- cipher/rijndael.c | 547 +++++++------ 5 files changed, 655 insertions(+), 3310 deletions(-) diff --git a/cipher/rijndael-amd64.S b/cipher/rijndael-amd64.S index 90e804b..5283895 100644 --- a/cipher/rijndael-amd64.S +++ b/cipher/rijndael-amd64.S @@ -31,24 +31,12 @@ .text /* table macros */ -#define E0 (.LtableE0-.LtableE0) -#define E1 (.LtableE1-.LtableE0) -#define E2 (.LtableE2-.LtableE0) -#define E3 (.LtableE3-.LtableE0) -#define Es0 (.LtableEs0-.LtableE0) -#define Es1 (.LtableEs1-.LtableE0) -#define Es2 (.LtableEs2-.LtableE0) -#define Es3 (.LtableEs3-.LtableE0) +#define E0 (0) +#define Es0 (4) #define Esize 8 -#define D0 (.LtableD0-.LtableD0) -#define D1 (.LtableD1-.LtableD0) -#define D2 (.LtableD2-.LtableD0) -#define D3 (.LtableD3-.LtableD0) -#define Ds0 (.LtableDs0-.LtableD0) -#define Ds1 (.LtableDs1-.LtableD0) -#define Ds2 (.LtableDs2-.LtableD0) -#define Ds3 (.LtableDs3-.LtableD0) +#define D0 (0) +#define Ds0 (4) #define Dsize 8 /* register macros */ @@ -115,38 +103,68 @@ xorl (((round) * 16) + 3 * 4)(CTX), rd ## d; #define do_encround(next_r) \ - do16bit_shr(16, mov, RA, Esize, E0, RNA, E1, RND, RT0, RT1); \ - do16bit( mov, RA, Esize, E2, RNC, E3, RNB, RT0, RT1); \ + do16bit_shr(16, mov, RA, Esize, E0, RNA, E0, RND, RT0, RT1); \ + do16bit( mov, RA, Esize, E0, RNC, E0, RNB, RT0, RT1); \ movl (((next_r) * 16) + 0 * 4)(CTX), RAd; \ + roll $8, RNDd; \ xorl RNAd, RAd; \ + roll $8, RNCd; \ + roll $8, RNBd; \ + roll $8, RAd; \ \ - do16bit_shr(16, xor, RD, Esize, E0, RND, E1, RNC, RT0, RT1); \ - do16bit( xor, RD, Esize, E2, RNB, E3, RA, RT0, RT1); \ + do16bit_shr(16, xor, RD, Esize, E0, RND, E0, RNC, RT0, RT1); \ + do16bit( xor, RD, Esize, E0, RNB, E0, RA, RT0, RT1); \ movl (((next_r) * 16) + 3 * 4)(CTX), RDd; \ + roll $8, RNCd; \ xorl RNDd, RDd; \ + roll $8, RNBd; \ + roll $8, RAd; \ + roll $8, RDd; \ \ - do16bit_shr(16, xor, RC, Esize, E0, RNC, E1, RNB, RT0, RT1); \ - do16bit( xor, RC, Esize, E2, RA, E3, RD, RT0, RT1); \ + do16bit_shr(16, xor, RC, Esize, E0, RNC, E0, RNB, RT0, RT1); \ + do16bit( xor, RC, Esize, E0, RA, E0, RD, RT0, RT1); \ movl (((next_r) * 16) + 2 * 4)(CTX), RCd; \ + roll $8, RNBd; \ xorl RNCd, RCd; \ + roll $8, RAd; \ + roll $8, RDd; \ + roll $8, RCd; \ \ - do16bit_shr(16, xor, RB, Esize, E0, RNB, E1, RA, RT0, RT1); \ - do16bit( xor, RB, Esize, E2, RD, E3, RC, RT0, RT1); \ + do16bit_shr(16, xor, RB, Esize, E0, RNB, E0, RA, RT0, RT1); \ + do16bit( xor, RB, Esize, E0, RD, E0, RC, RT0, RT1); \ movl (((next_r) * 16) + 1 * 4)(CTX), RBd; \ - xorl RNBd, RBd; + roll $8, RAd; \ + xorl RNBd, RBd; \ + roll $16, RDd; \ + roll $24, RCd; #define do_lastencround(next_r) \ - do16bit_shr(16, mov, RA, Esize, Es0, RNA, Es1, RND, RT0, RT1); \ - do16bit( mov, RA, Esize, Es2, RNC, Es3, RNB, RT0, RT1); \ + do16bit_shr(16, mov, RA, Esize, Es0, RNA, Es0, RND, RT0, RT1); \ + do16bit( mov, RA, Esize, Es0, RNC, Es0, RNB, RT0, RT1); \ + rorl $8, RNAd; \ + rorl $8, RNDd; \ + rorl $8, RNCd; \ + rorl $8, RNBd; \ \ - do16bit_shr(16, or, RB, Esize, Es0, RNB, Es1, RNA, RT0, RT1); \ - do16bit( or, RB, Esize, Es2, RND, Es3, RNC, RT0, RT1); \ + do16bit_shr(16, or, RB, Esize, Es0, RNB, Es0, RNA, RT0, RT1); \ + do16bit( or, RB, Esize, Es0, RND, Es0, RNC, RT0, RT1); \ + rorl $8, RNBd; \ + rorl $8, RNAd; \ + rorl $8, RNDd; \ + rorl $8, RNCd; \ \ - do16bit_shr(16, or, RC, Esize, Es0, RNC, Es1, RNB, RT0, RT1); \ - do16bit( or, RC, Esize, Es2, RNA, Es3, RND, RT0, RT1); \ + do16bit_shr(16, or, RC, Esize, Es0, RNC, Es0, RNB, RT0, RT1); \ + do16bit( or, RC, Esize, Es0, RNA, Es0, RND, RT0, RT1); \ + rorl $8, RNCd; \ + rorl $8, RNBd; \ + rorl $8, RNAd; \ + rorl $8, RNDd; \ \ - do16bit_shr(16, or, RD, Esize, Es0, RND, Es1, RNC, RT0, RT1); \ - do16bit( or, RD, Esize, Es2, RNB, Es3, RNA, RT0, RT1); + do16bit_shr(16, or, RD, Esize, Es0, RND, Es0, RNC, RT0, RT1); \ + do16bit( or, RD, Esize, Es0, RNB, Es0, RNA, RT0, RT1); \ + roll $8, RNCd; \ + roll $16, RNBd; \ + roll $24, RNAd; #define firstencround(round) \ addroundkey(round, RA, RB, RC, RD); \ @@ -169,6 +187,7 @@ _gcry_aes_amd64_encrypt_block: * %rsi: dst * %rdx: src * %ecx: number of rounds.. 10, 12 or 14 + * %r8: encryption tables */ subq $(5 * 8), %rsp; movq %rsi, (0 * 8)(%rsp); @@ -177,7 +196,7 @@ _gcry_aes_amd64_encrypt_block: movq %rbx, (3 * 8)(%rsp); movq %r12, (4 * 8)(%rsp); - leaq .LtableE0 RIP, RTAB; + leaq (%r8), RTAB; /* read input block */ movl 0 * 4(%rdx), RAd; @@ -212,7 +231,7 @@ _gcry_aes_amd64_encrypt_block: movq (2 * 8)(%rsp), %rbp; addq $(5 * 8), %rsp; - movl $(6 * 8), %eax; + movl $(6 * 8), %eax; ret; .align 4 @@ -237,38 +256,68 @@ _gcry_aes_amd64_encrypt_block: .size _gcry_aes_amd64_encrypt_block,.-_gcry_aes_amd64_encrypt_block; #define do_decround(next_r) \ - do16bit_shr(16, mov, RA, Dsize, D0, RNA, D1, RNB, RT0, RT1); \ - do16bit( mov, RA, Dsize, D2, RNC, D3, RND, RT0, RT1); \ + do16bit_shr(16, mov, RA, Dsize, D0, RNA, D0, RNB, RT0, RT1); \ + do16bit( mov, RA, Dsize, D0, RNC, D0, RND, RT0, RT1); \ movl (((next_r) * 16) + 0 * 4)(CTX), RAd; \ + roll $8, RNBd; \ xorl RNAd, RAd; \ + roll $8, RNCd; \ + roll $8, RNDd; \ + roll $8, RAd; \ \ - do16bit_shr(16, xor, RB, Dsize, D0, RNB, D1, RNC, RT0, RT1); \ - do16bit( xor, RB, Dsize, D2, RND, D3, RA, RT0, RT1); \ + do16bit_shr(16, xor, RB, Dsize, D0, RNB, D0, RNC, RT0, RT1); \ + do16bit( xor, RB, Dsize, D0, RND, D0, RA, RT0, RT1); \ movl (((next_r) * 16) + 1 * 4)(CTX), RBd; \ + roll $8, RNCd; \ xorl RNBd, RBd; \ + roll $8, RNDd; \ + roll $8, RAd; \ + roll $8, RBd; \ \ - do16bit_shr(16, xor, RC, Dsize, D0, RNC, D1, RND, RT0, RT1); \ - do16bit( xor, RC, Dsize, D2, RA, D3, RB, RT0, RT1); \ + do16bit_shr(16, xor, RC, Dsize, D0, RNC, D0, RND, RT0, RT1); \ + do16bit( xor, RC, Dsize, D0, RA, D0, RB, RT0, RT1); \ movl (((next_r) * 16) + 2 * 4)(CTX), RCd; \ + roll $8, RNDd; \ xorl RNCd, RCd; \ + roll $8, RAd; \ + roll $8, RBd; \ + roll $8, RCd; \ \ - do16bit_shr(16, xor, RD, Dsize, D0, RND, D1, RA, RT0, RT1); \ - do16bit( xor, RD, Dsize, D2, RB, D3, RC, RT0, RT1); \ + do16bit_shr(16, xor, RD, Dsize, D0, RND, D0, RA, RT0, RT1); \ + do16bit( xor, RD, Dsize, D0, RB, D0, RC, RT0, RT1); \ movl (((next_r) * 16) + 3 * 4)(CTX), RDd; \ + roll $8, RAd; \ xorl RNDd, RDd; \ + roll $16, RBd; \ + roll $24, RCd; #define do_lastdecround() \ - do16bit_shr(16, mov, RA, Dsize, Ds0, RNA, Ds1, RNB, RT0, RT1); \ - do16bit( mov, RA, Dsize, Ds2, RNC, Ds3, RND, RT0, RT1); \ + do16bit_shr(16, mov, RA, Dsize, Ds0, RNA, Ds0, RNB, RT0, RT1); \ + do16bit( mov, RA, Dsize, Ds0, RNC, Ds0, RND, RT0, RT1); \ + roll $8, RNAd; \ + roll $8, RNBd; \ + roll $8, RNCd; \ + roll $8, RNDd; \ \ - do16bit_shr(16, or, RB, Dsize, Ds0, RNB, Ds1, RNC, RT0, RT1); \ - do16bit( or, RB, Dsize, Ds2, RND, Ds3, RNA, RT0, RT1); \ + do16bit_shr(16, or, RB, Dsize, Ds0, RNB, Ds0, RNC, RT0, RT1); \ + do16bit( or, RB, Dsize, Ds0, RND, Ds0, RNA, RT0, RT1); \ + roll $8, RNBd; \ + roll $8, RNCd; \ + roll $8, RNDd; \ + roll $8, RNAd; \ \ - do16bit_shr(16, or, RC, Dsize, Ds0, RNC, Ds1, RND, RT0, RT1); \ - do16bit( or, RC, Dsize, Ds2, RNA, Ds3, RNB, RT0, RT1); \ + do16bit_shr(16, or, RC, Dsize, Ds0, RNC, Ds0, RND, RT0, RT1); \ + do16bit( or, RC, Dsize, Ds0, RNA, Ds0, RNB, RT0, RT1); \ + roll $8, RNCd; \ + roll $8, RNDd; \ + roll $8, RNAd; \ + roll $8, RNBd; \ \ - do16bit_shr(16, or, RD, Dsize, Ds0, RND, Ds1, RNA, RT0, RT1); \ - do16bit( or, RD, Dsize, Ds2, RNB, Ds3, RNC, RT0, RT1); + do16bit_shr(16, or, RD, Dsize, Ds0, RND, Ds0, RNA, RT0, RT1); \ + do16bit( or, RD, Dsize, Ds0, RNB, Ds0, RNC, RT0, RT1); \ + roll $8, RNAd; \ + roll $16, RNBd; \ + roll $24, RNCd; #define firstdecround(round) \ addroundkey((round + 1), RA, RB, RC, RD); \ @@ -291,6 +340,7 @@ _gcry_aes_amd64_decrypt_block: * %rsi: dst * %rdx: src * %ecx: number of rounds.. 10, 12 or 14 + * %r8: decryption tables */ subq $(5 * 8), %rsp; movq %rsi, (0 * 8)(%rsp); @@ -299,7 +349,7 @@ _gcry_aes_amd64_decrypt_block: movq %rbx, (3 * 8)(%rsp); movq %r12, (4 * 8)(%rsp); - leaq .LtableD0 RIP, RTAB; + leaq (%r8), RTAB; /* read input block */ movl 0 * 4(%rdx), RAd; @@ -335,7 +385,7 @@ _gcry_aes_amd64_decrypt_block: movq (2 * 8)(%rsp), %rbp; addq $(5 * 8), %rsp; - movl $(6 * 8), %eax; + movl $(6 * 8), %eax; ret; .align 4 @@ -359,1060 +409,5 @@ _gcry_aes_amd64_decrypt_block: jmp .Ldec_tail; .size _gcry_aes_amd64_decrypt_block,.-_gcry_aes_amd64_decrypt_block; -.data -.align 16 - -/* Encryption tables */ -.LtableE0: -.long 0xa56363c6 -.LtableEs0: -.long 0x00000063, 0x847c7cf8, 0x0000007c -.long 0x997777ee, 0x00000077, 0x8d7b7bf6, 0x0000007b -.long 0x0df2f2ff, 0x000000f2, 0xbd6b6bd6, 0x0000006b -.long 0xb16f6fde, 0x0000006f, 0x54c5c591, 0x000000c5 -.long 0x50303060, 0x00000030, 0x03010102, 0x00000001 -.long 0xa96767ce, 0x00000067, 0x7d2b2b56, 0x0000002b -.long 0x19fefee7, 0x000000fe, 0x62d7d7b5, 0x000000d7 -.long 0xe6abab4d, 0x000000ab, 0x9a7676ec, 0x00000076 -.long 0x45caca8f, 0x000000ca, 0x9d82821f, 0x00000082 -.long 0x40c9c989, 0x000000c9, 0x877d7dfa, 0x0000007d -.long 0x15fafaef, 0x000000fa, 0xeb5959b2, 0x00000059 -.long 0xc947478e, 0x00000047, 0x0bf0f0fb, 0x000000f0 -.long 0xecadad41, 0x000000ad, 0x67d4d4b3, 0x000000d4 -.long 0xfda2a25f, 0x000000a2, 0xeaafaf45, 0x000000af -.long 0xbf9c9c23, 0x0000009c, 0xf7a4a453, 0x000000a4 -.long 0x967272e4, 0x00000072, 0x5bc0c09b, 0x000000c0 -.long 0xc2b7b775, 0x000000b7, 0x1cfdfde1, 0x000000fd -.long 0xae93933d, 0x00000093, 0x6a26264c, 0x00000026 -.long 0x5a36366c, 0x00000036, 0x413f3f7e, 0x0000003f -.long 0x02f7f7f5, 0x000000f7, 0x4fcccc83, 0x000000cc -.long 0x5c343468, 0x00000034, 0xf4a5a551, 0x000000a5 -.long 0x34e5e5d1, 0x000000e5, 0x08f1f1f9, 0x000000f1 -.long 0x937171e2, 0x00000071, 0x73d8d8ab, 0x000000d8 -.long 0x53313162, 0x00000031, 0x3f15152a, 0x00000015 -.long 0x0c040408, 0x00000004, 0x52c7c795, 0x000000c7 -.long 0x65232346, 0x00000023, 0x5ec3c39d, 0x000000c3 -.long 0x28181830, 0x00000018, 0xa1969637, 0x00000096 -.long 0x0f05050a, 0x00000005, 0xb59a9a2f, 0x0000009a -.long 0x0907070e, 0x00000007, 0x36121224, 0x00000012 -.long 0x9b80801b, 0x00000080, 0x3de2e2df, 0x000000e2 -.long 0x26ebebcd, 0x000000eb, 0x6927274e, 0x00000027 -.long 0xcdb2b27f, 0x000000b2, 0x9f7575ea, 0x00000075 -.long 0x1b090912, 0x00000009, 0x9e83831d, 0x00000083 -.long 0x742c2c58, 0x0000002c, 0x2e1a1a34, 0x0000001a -.long 0x2d1b1b36, 0x0000001b, 0xb26e6edc, 0x0000006e -.long 0xee5a5ab4, 0x0000005a, 0xfba0a05b, 0x000000a0 -.long 0xf65252a4, 0x00000052, 0x4d3b3b76, 0x0000003b -.long 0x61d6d6b7, 0x000000d6, 0xceb3b37d, 0x000000b3 -.long 0x7b292952, 0x00000029, 0x3ee3e3dd, 0x000000e3 -.long 0x712f2f5e, 0x0000002f, 0x97848413, 0x00000084 -.long 0xf55353a6, 0x00000053, 0x68d1d1b9, 0x000000d1 -.long 0x00000000, 0x00000000, 0x2cededc1, 0x000000ed -.long 0x60202040, 0x00000020, 0x1ffcfce3, 0x000000fc -.long 0xc8b1b179, 0x000000b1, 0xed5b5bb6, 0x0000005b -.long 0xbe6a6ad4, 0x0000006a, 0x46cbcb8d, 0x000000cb -.long 0xd9bebe67, 0x000000be, 0x4b393972, 0x00000039 -.long 0xde4a4a94, 0x0000004a, 0xd44c4c98, 0x0000004c -.long 0xe85858b0, 0x00000058, 0x4acfcf85, 0x000000cf -.long 0x6bd0d0bb, 0x000000d0, 0x2aefefc5, 0x000000ef -.long 0xe5aaaa4f, 0x000000aa, 0x16fbfbed, 0x000000fb -.long 0xc5434386, 0x00000043, 0xd74d4d9a, 0x0000004d -.long 0x55333366, 0x00000033, 0x94858511, 0x00000085 -.long 0xcf45458a, 0x00000045, 0x10f9f9e9, 0x000000f9 -.long 0x06020204, 0x00000002, 0x817f7ffe, 0x0000007f -.long 0xf05050a0, 0x00000050, 0x443c3c78, 0x0000003c -.long 0xba9f9f25, 0x0000009f, 0xe3a8a84b, 0x000000a8 -.long 0xf35151a2, 0x00000051, 0xfea3a35d, 0x000000a3 -.long 0xc0404080, 0x00000040, 0x8a8f8f05, 0x0000008f -.long 0xad92923f, 0x00000092, 0xbc9d9d21, 0x0000009d -.long 0x48383870, 0x00000038, 0x04f5f5f1, 0x000000f5 -.long 0xdfbcbc63, 0x000000bc, 0xc1b6b677, 0x000000b6 -.long 0x75dadaaf, 0x000000da, 0x63212142, 0x00000021 -.long 0x30101020, 0x00000010, 0x1affffe5, 0x000000ff -.long 0x0ef3f3fd, 0x000000f3, 0x6dd2d2bf, 0x000000d2 -.long 0x4ccdcd81, 0x000000cd, 0x140c0c18, 0x0000000c -.long 0x35131326, 0x00000013, 0x2fececc3, 0x000000ec -.long 0xe15f5fbe, 0x0000005f, 0xa2979735, 0x00000097 -.long 0xcc444488, 0x00000044, 0x3917172e, 0x00000017 -.long 0x57c4c493, 0x000000c4, 0xf2a7a755, 0x000000a7 -.long 0x827e7efc, 0x0000007e, 0x473d3d7a, 0x0000003d -.long 0xac6464c8, 0x00000064, 0xe75d5dba, 0x0000005d -.long 0x2b191932, 0x00000019, 0x957373e6, 0x00000073 -.long 0xa06060c0, 0x00000060, 0x98818119, 0x00000081 -.long 0xd14f4f9e, 0x0000004f, 0x7fdcdca3, 0x000000dc -.long 0x66222244, 0x00000022, 0x7e2a2a54, 0x0000002a -.long 0xab90903b, 0x00000090, 0x8388880b, 0x00000088 -.long 0xca46468c, 0x00000046, 0x29eeeec7, 0x000000ee -.long 0xd3b8b86b, 0x000000b8, 0x3c141428, 0x00000014 -.long 0x79dedea7, 0x000000de, 0xe25e5ebc, 0x0000005e -.long 0x1d0b0b16, 0x0000000b, 0x76dbdbad, 0x000000db -.long 0x3be0e0db, 0x000000e0, 0x56323264, 0x00000032 -.long 0x4e3a3a74, 0x0000003a, 0x1e0a0a14, 0x0000000a -.long 0xdb494992, 0x00000049, 0x0a06060c, 0x00000006 -.long 0x6c242448, 0x00000024, 0xe45c5cb8, 0x0000005c -.long 0x5dc2c29f, 0x000000c2, 0x6ed3d3bd, 0x000000d3 -.long 0xefacac43, 0x000000ac, 0xa66262c4, 0x00000062 -.long 0xa8919139, 0x00000091, 0xa4959531, 0x00000095 -.long 0x37e4e4d3, 0x000000e4, 0x8b7979f2, 0x00000079 -.long 0x32e7e7d5, 0x000000e7, 0x43c8c88b, 0x000000c8 -.long 0x5937376e, 0x00000037, 0xb76d6dda, 0x0000006d -.long 0x8c8d8d01, 0x0000008d, 0x64d5d5b1, 0x000000d5 -.long 0xd24e4e9c, 0x0000004e, 0xe0a9a949, 0x000000a9 -.long 0xb46c6cd8, 0x0000006c, 0xfa5656ac, 0x00000056 -.long 0x07f4f4f3, 0x000000f4, 0x25eaeacf, 0x000000ea -.long 0xaf6565ca, 0x00000065, 0x8e7a7af4, 0x0000007a -.long 0xe9aeae47, 0x000000ae, 0x18080810, 0x00000008 -.long 0xd5baba6f, 0x000000ba, 0x887878f0, 0x00000078 -.long 0x6f25254a, 0x00000025, 0x722e2e5c, 0x0000002e -.long 0x241c1c38, 0x0000001c, 0xf1a6a657, 0x000000a6 -.long 0xc7b4b473, 0x000000b4, 0x51c6c697, 0x000000c6 -.long 0x23e8e8cb, 0x000000e8, 0x7cdddda1, 0x000000dd -.long 0x9c7474e8, 0x00000074, 0x211f1f3e, 0x0000001f -.long 0xdd4b4b96, 0x0000004b, 0xdcbdbd61, 0x000000bd -.long 0x868b8b0d, 0x0000008b, 0x858a8a0f, 0x0000008a -.long 0x907070e0, 0x00000070, 0x423e3e7c, 0x0000003e -.long 0xc4b5b571, 0x000000b5, 0xaa6666cc, 0x00000066 -.long 0xd8484890, 0x00000048, 0x05030306, 0x00000003 -.long 0x01f6f6f7, 0x000000f6, 0x120e0e1c, 0x0000000e -.long 0xa36161c2, 0x00000061, 0x5f35356a, 0x00000035 -.long 0xf95757ae, 0x00000057, 0xd0b9b969, 0x000000b9 -.long 0x91868617, 0x00000086, 0x58c1c199, 0x000000c1 -.long 0x271d1d3a, 0x0000001d, 0xb99e9e27, 0x0000009e -.long 0x38e1e1d9, 0x000000e1, 0x13f8f8eb, 0x000000f8 -.long 0xb398982b, 0x00000098, 0x33111122, 0x00000011 -.long 0xbb6969d2, 0x00000069, 0x70d9d9a9, 0x000000d9 -.long 0x898e8e07, 0x0000008e, 0xa7949433, 0x00000094 -.long 0xb69b9b2d, 0x0000009b, 0x221e1e3c, 0x0000001e -.long 0x92878715, 0x00000087, 0x20e9e9c9, 0x000000e9 -.long 0x49cece87, 0x000000ce, 0xff5555aa, 0x00000055 -.long 0x78282850, 0x00000028, 0x7adfdfa5, 0x000000df -.long 0x8f8c8c03, 0x0000008c, 0xf8a1a159, 0x000000a1 -.long 0x80898909, 0x00000089, 0x170d0d1a, 0x0000000d -.long 0xdabfbf65, 0x000000bf, 0x31e6e6d7, 0x000000e6 -.long 0xc6424284, 0x00000042, 0xb86868d0, 0x00000068 -.long 0xc3414182, 0x00000041, 0xb0999929, 0x00000099 -.long 0x772d2d5a, 0x0000002d, 0x110f0f1e, 0x0000000f -.long 0xcbb0b07b, 0x000000b0, 0xfc5454a8, 0x00000054 -.long 0xd6bbbb6d, 0x000000bb, 0x3a16162c, 0x00000016 -.LtableE1: -.long 0x6363c6a5 -.LtableEs1: -.long 0x00006300, 0x7c7cf884, 0x00007c00 -.long 0x7777ee99, 0x00007700, 0x7b7bf68d, 0x00007b00 -.long 0xf2f2ff0d, 0x0000f200, 0x6b6bd6bd, 0x00006b00 -.long 0x6f6fdeb1, 0x00006f00, 0xc5c59154, 0x0000c500 -.long 0x30306050, 0x00003000, 0x01010203, 0x00000100 -.long 0x6767cea9, 0x00006700, 0x2b2b567d, 0x00002b00 -.long 0xfefee719, 0x0000fe00, 0xd7d7b562, 0x0000d700 -.long 0xabab4de6, 0x0000ab00, 0x7676ec9a, 0x00007600 -.long 0xcaca8f45, 0x0000ca00, 0x82821f9d, 0x00008200 -.long 0xc9c98940, 0x0000c900, 0x7d7dfa87, 0x00007d00 -.long 0xfafaef15, 0x0000fa00, 0x5959b2eb, 0x00005900 -.long 0x47478ec9, 0x00004700, 0xf0f0fb0b, 0x0000f000 -.long 0xadad41ec, 0x0000ad00, 0xd4d4b367, 0x0000d400 -.long 0xa2a25ffd, 0x0000a200, 0xafaf45ea, 0x0000af00 -.long 0x9c9c23bf, 0x00009c00, 0xa4a453f7, 0x0000a400 -.long 0x7272e496, 0x00007200, 0xc0c09b5b, 0x0000c000 -.long 0xb7b775c2, 0x0000b700, 0xfdfde11c, 0x0000fd00 -.long 0x93933dae, 0x00009300, 0x26264c6a, 0x00002600 -.long 0x36366c5a, 0x00003600, 0x3f3f7e41, 0x00003f00 -.long 0xf7f7f502, 0x0000f700, 0xcccc834f, 0x0000cc00 -.long 0x3434685c, 0x00003400, 0xa5a551f4, 0x0000a500 -.long 0xe5e5d134, 0x0000e500, 0xf1f1f908, 0x0000f100 -.long 0x7171e293, 0x00007100, 0xd8d8ab73, 0x0000d800 -.long 0x31316253, 0x00003100, 0x15152a3f, 0x00001500 -.long 0x0404080c, 0x00000400, 0xc7c79552, 0x0000c700 -.long 0x23234665, 0x00002300, 0xc3c39d5e, 0x0000c300 -.long 0x18183028, 0x00001800, 0x969637a1, 0x00009600 -.long 0x05050a0f, 0x00000500, 0x9a9a2fb5, 0x00009a00 -.long 0x07070e09, 0x00000700, 0x12122436, 0x00001200 -.long 0x80801b9b, 0x00008000, 0xe2e2df3d, 0x0000e200 -.long 0xebebcd26, 0x0000eb00, 0x27274e69, 0x00002700 -.long 0xb2b27fcd, 0x0000b200, 0x7575ea9f, 0x00007500 -.long 0x0909121b, 0x00000900, 0x83831d9e, 0x00008300 -.long 0x2c2c5874, 0x00002c00, 0x1a1a342e, 0x00001a00 -.long 0x1b1b362d, 0x00001b00, 0x6e6edcb2, 0x00006e00 -.long 0x5a5ab4ee, 0x00005a00, 0xa0a05bfb, 0x0000a000 -.long 0x5252a4f6, 0x00005200, 0x3b3b764d, 0x00003b00 -.long 0xd6d6b761, 0x0000d600, 0xb3b37dce, 0x0000b300 -.long 0x2929527b, 0x00002900, 0xe3e3dd3e, 0x0000e300 -.long 0x2f2f5e71, 0x00002f00, 0x84841397, 0x00008400 -.long 0x5353a6f5, 0x00005300, 0xd1d1b968, 0x0000d100 -.long 0x00000000, 0x00000000, 0xededc12c, 0x0000ed00 -.long 0x20204060, 0x00002000, 0xfcfce31f, 0x0000fc00 -.long 0xb1b179c8, 0x0000b100, 0x5b5bb6ed, 0x00005b00 -.long 0x6a6ad4be, 0x00006a00, 0xcbcb8d46, 0x0000cb00 -.long 0xbebe67d9, 0x0000be00, 0x3939724b, 0x00003900 -.long 0x4a4a94de, 0x00004a00, 0x4c4c98d4, 0x00004c00 -.long 0x5858b0e8, 0x00005800, 0xcfcf854a, 0x0000cf00 -.long 0xd0d0bb6b, 0x0000d000, 0xefefc52a, 0x0000ef00 -.long 0xaaaa4fe5, 0x0000aa00, 0xfbfbed16, 0x0000fb00 -.long 0x434386c5, 0x00004300, 0x4d4d9ad7, 0x00004d00 -.long 0x33336655, 0x00003300, 0x85851194, 0x00008500 -.long 0x45458acf, 0x00004500, 0xf9f9e910, 0x0000f900 -.long 0x02020406, 0x00000200, 0x7f7ffe81, 0x00007f00 -.long 0x5050a0f0, 0x00005000, 0x3c3c7844, 0x00003c00 -.long 0x9f9f25ba, 0x00009f00, 0xa8a84be3, 0x0000a800 -.long 0x5151a2f3, 0x00005100, 0xa3a35dfe, 0x0000a300 -.long 0x404080c0, 0x00004000, 0x8f8f058a, 0x00008f00 -.long 0x92923fad, 0x00009200, 0x9d9d21bc, 0x00009d00 -.long 0x38387048, 0x00003800, 0xf5f5f104, 0x0000f500 -.long 0xbcbc63df, 0x0000bc00, 0xb6b677c1, 0x0000b600 -.long 0xdadaaf75, 0x0000da00, 0x21214263, 0x00002100 -.long 0x10102030, 0x00001000, 0xffffe51a, 0x0000ff00 -.long 0xf3f3fd0e, 0x0000f300, 0xd2d2bf6d, 0x0000d200 -.long 0xcdcd814c, 0x0000cd00, 0x0c0c1814, 0x00000c00 -.long 0x13132635, 0x00001300, 0xececc32f, 0x0000ec00 -.long 0x5f5fbee1, 0x00005f00, 0x979735a2, 0x00009700 -.long 0x444488cc, 0x00004400, 0x17172e39, 0x00001700 -.long 0xc4c49357, 0x0000c400, 0xa7a755f2, 0x0000a700 -.long 0x7e7efc82, 0x00007e00, 0x3d3d7a47, 0x00003d00 -.long 0x6464c8ac, 0x00006400, 0x5d5dbae7, 0x00005d00 -.long 0x1919322b, 0x00001900, 0x7373e695, 0x00007300 -.long 0x6060c0a0, 0x00006000, 0x81811998, 0x00008100 -.long 0x4f4f9ed1, 0x00004f00, 0xdcdca37f, 0x0000dc00 -.long 0x22224466, 0x00002200, 0x2a2a547e, 0x00002a00 -.long 0x90903bab, 0x00009000, 0x88880b83, 0x00008800 -.long 0x46468cca, 0x00004600, 0xeeeec729, 0x0000ee00 -.long 0xb8b86bd3, 0x0000b800, 0x1414283c, 0x00001400 -.long 0xdedea779, 0x0000de00, 0x5e5ebce2, 0x00005e00 -.long 0x0b0b161d, 0x00000b00, 0xdbdbad76, 0x0000db00 -.long 0xe0e0db3b, 0x0000e000, 0x32326456, 0x00003200 -.long 0x3a3a744e, 0x00003a00, 0x0a0a141e, 0x00000a00 -.long 0x494992db, 0x00004900, 0x06060c0a, 0x00000600 -.long 0x2424486c, 0x00002400, 0x5c5cb8e4, 0x00005c00 -.long 0xc2c29f5d, 0x0000c200, 0xd3d3bd6e, 0x0000d300 -.long 0xacac43ef, 0x0000ac00, 0x6262c4a6, 0x00006200 -.long 0x919139a8, 0x00009100, 0x959531a4, 0x00009500 -.long 0xe4e4d337, 0x0000e400, 0x7979f28b, 0x00007900 -.long 0xe7e7d532, 0x0000e700, 0xc8c88b43, 0x0000c800 -.long 0x37376e59, 0x00003700, 0x6d6ddab7, 0x00006d00 -.long 0x8d8d018c, 0x00008d00, 0xd5d5b164, 0x0000d500 -.long 0x4e4e9cd2, 0x00004e00, 0xa9a949e0, 0x0000a900 -.long 0x6c6cd8b4, 0x00006c00, 0x5656acfa, 0x00005600 -.long 0xf4f4f307, 0x0000f400, 0xeaeacf25, 0x0000ea00 -.long 0x6565caaf, 0x00006500, 0x7a7af48e, 0x00007a00 -.long 0xaeae47e9, 0x0000ae00, 0x08081018, 0x00000800 -.long 0xbaba6fd5, 0x0000ba00, 0x7878f088, 0x00007800 -.long 0x25254a6f, 0x00002500, 0x2e2e5c72, 0x00002e00 -.long 0x1c1c3824, 0x00001c00, 0xa6a657f1, 0x0000a600 -.long 0xb4b473c7, 0x0000b400, 0xc6c69751, 0x0000c600 -.long 0xe8e8cb23, 0x0000e800, 0xdddda17c, 0x0000dd00 -.long 0x7474e89c, 0x00007400, 0x1f1f3e21, 0x00001f00 -.long 0x4b4b96dd, 0x00004b00, 0xbdbd61dc, 0x0000bd00 -.long 0x8b8b0d86, 0x00008b00, 0x8a8a0f85, 0x00008a00 -.long 0x7070e090, 0x00007000, 0x3e3e7c42, 0x00003e00 -.long 0xb5b571c4, 0x0000b500, 0x6666ccaa, 0x00006600 -.long 0x484890d8, 0x00004800, 0x03030605, 0x00000300 -.long 0xf6f6f701, 0x0000f600, 0x0e0e1c12, 0x00000e00 -.long 0x6161c2a3, 0x00006100, 0x35356a5f, 0x00003500 -.long 0x5757aef9, 0x00005700, 0xb9b969d0, 0x0000b900 -.long 0x86861791, 0x00008600, 0xc1c19958, 0x0000c100 -.long 0x1d1d3a27, 0x00001d00, 0x9e9e27b9, 0x00009e00 -.long 0xe1e1d938, 0x0000e100, 0xf8f8eb13, 0x0000f800 -.long 0x98982bb3, 0x00009800, 0x11112233, 0x00001100 -.long 0x6969d2bb, 0x00006900, 0xd9d9a970, 0x0000d900 -.long 0x8e8e0789, 0x00008e00, 0x949433a7, 0x00009400 -.long 0x9b9b2db6, 0x00009b00, 0x1e1e3c22, 0x00001e00 -.long 0x87871592, 0x00008700, 0xe9e9c920, 0x0000e900 -.long 0xcece8749, 0x0000ce00, 0x5555aaff, 0x00005500 -.long 0x28285078, 0x00002800, 0xdfdfa57a, 0x0000df00 -.long 0x8c8c038f, 0x00008c00, 0xa1a159f8, 0x0000a100 -.long 0x89890980, 0x00008900, 0x0d0d1a17, 0x00000d00 -.long 0xbfbf65da, 0x0000bf00, 0xe6e6d731, 0x0000e600 -.long 0x424284c6, 0x00004200, 0x6868d0b8, 0x00006800 -.long 0x414182c3, 0x00004100, 0x999929b0, 0x00009900 -.long 0x2d2d5a77, 0x00002d00, 0x0f0f1e11, 0x00000f00 -.long 0xb0b07bcb, 0x0000b000, 0x5454a8fc, 0x00005400 -.long 0xbbbb6dd6, 0x0000bb00, 0x16162c3a, 0x00001600 -.LtableE2: -.long 0x63c6a563 -.LtableEs2: -.long 0x00630000, 0x7cf8847c, 0x007c0000 -.long 0x77ee9977, 0x00770000, 0x7bf68d7b, 0x007b0000 -.long 0xf2ff0df2, 0x00f20000, 0x6bd6bd6b, 0x006b0000 -.long 0x6fdeb16f, 0x006f0000, 0xc59154c5, 0x00c50000 -.long 0x30605030, 0x00300000, 0x01020301, 0x00010000 -.long 0x67cea967, 0x00670000, 0x2b567d2b, 0x002b0000 -.long 0xfee719fe, 0x00fe0000, 0xd7b562d7, 0x00d70000 -.long 0xab4de6ab, 0x00ab0000, 0x76ec9a76, 0x00760000 -.long 0xca8f45ca, 0x00ca0000, 0x821f9d82, 0x00820000 -.long 0xc98940c9, 0x00c90000, 0x7dfa877d, 0x007d0000 -.long 0xfaef15fa, 0x00fa0000, 0x59b2eb59, 0x00590000 -.long 0x478ec947, 0x00470000, 0xf0fb0bf0, 0x00f00000 -.long 0xad41ecad, 0x00ad0000, 0xd4b367d4, 0x00d40000 -.long 0xa25ffda2, 0x00a20000, 0xaf45eaaf, 0x00af0000 -.long 0x9c23bf9c, 0x009c0000, 0xa453f7a4, 0x00a40000 -.long 0x72e49672, 0x00720000, 0xc09b5bc0, 0x00c00000 -.long 0xb775c2b7, 0x00b70000, 0xfde11cfd, 0x00fd0000 -.long 0x933dae93, 0x00930000, 0x264c6a26, 0x00260000 -.long 0x366c5a36, 0x00360000, 0x3f7e413f, 0x003f0000 -.long 0xf7f502f7, 0x00f70000, 0xcc834fcc, 0x00cc0000 -.long 0x34685c34, 0x00340000, 0xa551f4a5, 0x00a50000 -.long 0xe5d134e5, 0x00e50000, 0xf1f908f1, 0x00f10000 -.long 0x71e29371, 0x00710000, 0xd8ab73d8, 0x00d80000 -.long 0x31625331, 0x00310000, 0x152a3f15, 0x00150000 -.long 0x04080c04, 0x00040000, 0xc79552c7, 0x00c70000 -.long 0x23466523, 0x00230000, 0xc39d5ec3, 0x00c30000 -.long 0x18302818, 0x00180000, 0x9637a196, 0x00960000 -.long 0x050a0f05, 0x00050000, 0x9a2fb59a, 0x009a0000 -.long 0x070e0907, 0x00070000, 0x12243612, 0x00120000 -.long 0x801b9b80, 0x00800000, 0xe2df3de2, 0x00e20000 -.long 0xebcd26eb, 0x00eb0000, 0x274e6927, 0x00270000 -.long 0xb27fcdb2, 0x00b20000, 0x75ea9f75, 0x00750000 -.long 0x09121b09, 0x00090000, 0x831d9e83, 0x00830000 -.long 0x2c58742c, 0x002c0000, 0x1a342e1a, 0x001a0000 -.long 0x1b362d1b, 0x001b0000, 0x6edcb26e, 0x006e0000 -.long 0x5ab4ee5a, 0x005a0000, 0xa05bfba0, 0x00a00000 -.long 0x52a4f652, 0x00520000, 0x3b764d3b, 0x003b0000 -.long 0xd6b761d6, 0x00d60000, 0xb37dceb3, 0x00b30000 -.long 0x29527b29, 0x00290000, 0xe3dd3ee3, 0x00e30000 -.long 0x2f5e712f, 0x002f0000, 0x84139784, 0x00840000 -.long 0x53a6f553, 0x00530000, 0xd1b968d1, 0x00d10000 -.long 0x00000000, 0x00000000, 0xedc12ced, 0x00ed0000 -.long 0x20406020, 0x00200000, 0xfce31ffc, 0x00fc0000 -.long 0xb179c8b1, 0x00b10000, 0x5bb6ed5b, 0x005b0000 -.long 0x6ad4be6a, 0x006a0000, 0xcb8d46cb, 0x00cb0000 -.long 0xbe67d9be, 0x00be0000, 0x39724b39, 0x00390000 -.long 0x4a94de4a, 0x004a0000, 0x4c98d44c, 0x004c0000 -.long 0x58b0e858, 0x00580000, 0xcf854acf, 0x00cf0000 -.long 0xd0bb6bd0, 0x00d00000, 0xefc52aef, 0x00ef0000 -.long 0xaa4fe5aa, 0x00aa0000, 0xfbed16fb, 0x00fb0000 -.long 0x4386c543, 0x00430000, 0x4d9ad74d, 0x004d0000 -.long 0x33665533, 0x00330000, 0x85119485, 0x00850000 -.long 0x458acf45, 0x00450000, 0xf9e910f9, 0x00f90000 -.long 0x02040602, 0x00020000, 0x7ffe817f, 0x007f0000 -.long 0x50a0f050, 0x00500000, 0x3c78443c, 0x003c0000 -.long 0x9f25ba9f, 0x009f0000, 0xa84be3a8, 0x00a80000 -.long 0x51a2f351, 0x00510000, 0xa35dfea3, 0x00a30000 -.long 0x4080c040, 0x00400000, 0x8f058a8f, 0x008f0000 -.long 0x923fad92, 0x00920000, 0x9d21bc9d, 0x009d0000 -.long 0x38704838, 0x00380000, 0xf5f104f5, 0x00f50000 -.long 0xbc63dfbc, 0x00bc0000, 0xb677c1b6, 0x00b60000 -.long 0xdaaf75da, 0x00da0000, 0x21426321, 0x00210000 -.long 0x10203010, 0x00100000, 0xffe51aff, 0x00ff0000 -.long 0xf3fd0ef3, 0x00f30000, 0xd2bf6dd2, 0x00d20000 -.long 0xcd814ccd, 0x00cd0000, 0x0c18140c, 0x000c0000 -.long 0x13263513, 0x00130000, 0xecc32fec, 0x00ec0000 -.long 0x5fbee15f, 0x005f0000, 0x9735a297, 0x00970000 -.long 0x4488cc44, 0x00440000, 0x172e3917, 0x00170000 -.long 0xc49357c4, 0x00c40000, 0xa755f2a7, 0x00a70000 -.long 0x7efc827e, 0x007e0000, 0x3d7a473d, 0x003d0000 -.long 0x64c8ac64, 0x00640000, 0x5dbae75d, 0x005d0000 -.long 0x19322b19, 0x00190000, 0x73e69573, 0x00730000 -.long 0x60c0a060, 0x00600000, 0x81199881, 0x00810000 -.long 0x4f9ed14f, 0x004f0000, 0xdca37fdc, 0x00dc0000 -.long 0x22446622, 0x00220000, 0x2a547e2a, 0x002a0000 -.long 0x903bab90, 0x00900000, 0x880b8388, 0x00880000 -.long 0x468cca46, 0x00460000, 0xeec729ee, 0x00ee0000 -.long 0xb86bd3b8, 0x00b80000, 0x14283c14, 0x00140000 -.long 0xdea779de, 0x00de0000, 0x5ebce25e, 0x005e0000 -.long 0x0b161d0b, 0x000b0000, 0xdbad76db, 0x00db0000 -.long 0xe0db3be0, 0x00e00000, 0x32645632, 0x00320000 -.long 0x3a744e3a, 0x003a0000, 0x0a141e0a, 0x000a0000 -.long 0x4992db49, 0x00490000, 0x060c0a06, 0x00060000 -.long 0x24486c24, 0x00240000, 0x5cb8e45c, 0x005c0000 -.long 0xc29f5dc2, 0x00c20000, 0xd3bd6ed3, 0x00d30000 -.long 0xac43efac, 0x00ac0000, 0x62c4a662, 0x00620000 -.long 0x9139a891, 0x00910000, 0x9531a495, 0x00950000 -.long 0xe4d337e4, 0x00e40000, 0x79f28b79, 0x00790000 -.long 0xe7d532e7, 0x00e70000, 0xc88b43c8, 0x00c80000 -.long 0x376e5937, 0x00370000, 0x6ddab76d, 0x006d0000 -.long 0x8d018c8d, 0x008d0000, 0xd5b164d5, 0x00d50000 -.long 0x4e9cd24e, 0x004e0000, 0xa949e0a9, 0x00a90000 -.long 0x6cd8b46c, 0x006c0000, 0x56acfa56, 0x00560000 -.long 0xf4f307f4, 0x00f40000, 0xeacf25ea, 0x00ea0000 -.long 0x65caaf65, 0x00650000, 0x7af48e7a, 0x007a0000 -.long 0xae47e9ae, 0x00ae0000, 0x08101808, 0x00080000 -.long 0xba6fd5ba, 0x00ba0000, 0x78f08878, 0x00780000 -.long 0x254a6f25, 0x00250000, 0x2e5c722e, 0x002e0000 -.long 0x1c38241c, 0x001c0000, 0xa657f1a6, 0x00a60000 -.long 0xb473c7b4, 0x00b40000, 0xc69751c6, 0x00c60000 -.long 0xe8cb23e8, 0x00e80000, 0xdda17cdd, 0x00dd0000 -.long 0x74e89c74, 0x00740000, 0x1f3e211f, 0x001f0000 -.long 0x4b96dd4b, 0x004b0000, 0xbd61dcbd, 0x00bd0000 -.long 0x8b0d868b, 0x008b0000, 0x8a0f858a, 0x008a0000 -.long 0x70e09070, 0x00700000, 0x3e7c423e, 0x003e0000 -.long 0xb571c4b5, 0x00b50000, 0x66ccaa66, 0x00660000 -.long 0x4890d848, 0x00480000, 0x03060503, 0x00030000 -.long 0xf6f701f6, 0x00f60000, 0x0e1c120e, 0x000e0000 -.long 0x61c2a361, 0x00610000, 0x356a5f35, 0x00350000 -.long 0x57aef957, 0x00570000, 0xb969d0b9, 0x00b90000 -.long 0x86179186, 0x00860000, 0xc19958c1, 0x00c10000 -.long 0x1d3a271d, 0x001d0000, 0x9e27b99e, 0x009e0000 -.long 0xe1d938e1, 0x00e10000, 0xf8eb13f8, 0x00f80000 -.long 0x982bb398, 0x00980000, 0x11223311, 0x00110000 -.long 0x69d2bb69, 0x00690000, 0xd9a970d9, 0x00d90000 -.long 0x8e07898e, 0x008e0000, 0x9433a794, 0x00940000 -.long 0x9b2db69b, 0x009b0000, 0x1e3c221e, 0x001e0000 -.long 0x87159287, 0x00870000, 0xe9c920e9, 0x00e90000 -.long 0xce8749ce, 0x00ce0000, 0x55aaff55, 0x00550000 -.long 0x28507828, 0x00280000, 0xdfa57adf, 0x00df0000 -.long 0x8c038f8c, 0x008c0000, 0xa159f8a1, 0x00a10000 -.long 0x89098089, 0x00890000, 0x0d1a170d, 0x000d0000 -.long 0xbf65dabf, 0x00bf0000, 0xe6d731e6, 0x00e60000 -.long 0x4284c642, 0x00420000, 0x68d0b868, 0x00680000 -.long 0x4182c341, 0x00410000, 0x9929b099, 0x00990000 -.long 0x2d5a772d, 0x002d0000, 0x0f1e110f, 0x000f0000 -.long 0xb07bcbb0, 0x00b00000, 0x54a8fc54, 0x00540000 -.long 0xbb6dd6bb, 0x00bb0000, 0x162c3a16, 0x00160000 -.LtableE3: -.long 0xc6a56363 -.LtableEs3: -.long 0x63000000, 0xf8847c7c, 0x7c000000 -.long 0xee997777, 0x77000000, 0xf68d7b7b, 0x7b000000 -.long 0xff0df2f2, 0xf2000000, 0xd6bd6b6b, 0x6b000000 -.long 0xdeb16f6f, 0x6f000000, 0x9154c5c5, 0xc5000000 -.long 0x60503030, 0x30000000, 0x02030101, 0x01000000 -.long 0xcea96767, 0x67000000, 0x567d2b2b, 0x2b000000 -.long 0xe719fefe, 0xfe000000, 0xb562d7d7, 0xd7000000 -.long 0x4de6abab, 0xab000000, 0xec9a7676, 0x76000000 -.long 0x8f45caca, 0xca000000, 0x1f9d8282, 0x82000000 -.long 0x8940c9c9, 0xc9000000, 0xfa877d7d, 0x7d000000 -.long 0xef15fafa, 0xfa000000, 0xb2eb5959, 0x59000000 -.long 0x8ec94747, 0x47000000, 0xfb0bf0f0, 0xf0000000 -.long 0x41ecadad, 0xad000000, 0xb367d4d4, 0xd4000000 -.long 0x5ffda2a2, 0xa2000000, 0x45eaafaf, 0xaf000000 -.long 0x23bf9c9c, 0x9c000000, 0x53f7a4a4, 0xa4000000 -.long 0xe4967272, 0x72000000, 0x9b5bc0c0, 0xc0000000 -.long 0x75c2b7b7, 0xb7000000, 0xe11cfdfd, 0xfd000000 -.long 0x3dae9393, 0x93000000, 0x4c6a2626, 0x26000000 -.long 0x6c5a3636, 0x36000000, 0x7e413f3f, 0x3f000000 -.long 0xf502f7f7, 0xf7000000, 0x834fcccc, 0xcc000000 -.long 0x685c3434, 0x34000000, 0x51f4a5a5, 0xa5000000 -.long 0xd134e5e5, 0xe5000000, 0xf908f1f1, 0xf1000000 -.long 0xe2937171, 0x71000000, 0xab73d8d8, 0xd8000000 -.long 0x62533131, 0x31000000, 0x2a3f1515, 0x15000000 -.long 0x080c0404, 0x04000000, 0x9552c7c7, 0xc7000000 -.long 0x46652323, 0x23000000, 0x9d5ec3c3, 0xc3000000 -.long 0x30281818, 0x18000000, 0x37a19696, 0x96000000 -.long 0x0a0f0505, 0x05000000, 0x2fb59a9a, 0x9a000000 -.long 0x0e090707, 0x07000000, 0x24361212, 0x12000000 -.long 0x1b9b8080, 0x80000000, 0xdf3de2e2, 0xe2000000 -.long 0xcd26ebeb, 0xeb000000, 0x4e692727, 0x27000000 -.long 0x7fcdb2b2, 0xb2000000, 0xea9f7575, 0x75000000 -.long 0x121b0909, 0x09000000, 0x1d9e8383, 0x83000000 -.long 0x58742c2c, 0x2c000000, 0x342e1a1a, 0x1a000000 -.long 0x362d1b1b, 0x1b000000, 0xdcb26e6e, 0x6e000000 -.long 0xb4ee5a5a, 0x5a000000, 0x5bfba0a0, 0xa0000000 -.long 0xa4f65252, 0x52000000, 0x764d3b3b, 0x3b000000 -.long 0xb761d6d6, 0xd6000000, 0x7dceb3b3, 0xb3000000 -.long 0x527b2929, 0x29000000, 0xdd3ee3e3, 0xe3000000 -.long 0x5e712f2f, 0x2f000000, 0x13978484, 0x84000000 -.long 0xa6f55353, 0x53000000, 0xb968d1d1, 0xd1000000 -.long 0x00000000, 0x00000000, 0xc12ceded, 0xed000000 -.long 0x40602020, 0x20000000, 0xe31ffcfc, 0xfc000000 -.long 0x79c8b1b1, 0xb1000000, 0xb6ed5b5b, 0x5b000000 -.long 0xd4be6a6a, 0x6a000000, 0x8d46cbcb, 0xcb000000 -.long 0x67d9bebe, 0xbe000000, 0x724b3939, 0x39000000 -.long 0x94de4a4a, 0x4a000000, 0x98d44c4c, 0x4c000000 -.long 0xb0e85858, 0x58000000, 0x854acfcf, 0xcf000000 -.long 0xbb6bd0d0, 0xd0000000, 0xc52aefef, 0xef000000 -.long 0x4fe5aaaa, 0xaa000000, 0xed16fbfb, 0xfb000000 -.long 0x86c54343, 0x43000000, 0x9ad74d4d, 0x4d000000 -.long 0x66553333, 0x33000000, 0x11948585, 0x85000000 -.long 0x8acf4545, 0x45000000, 0xe910f9f9, 0xf9000000 -.long 0x04060202, 0x02000000, 0xfe817f7f, 0x7f000000 -.long 0xa0f05050, 0x50000000, 0x78443c3c, 0x3c000000 -.long 0x25ba9f9f, 0x9f000000, 0x4be3a8a8, 0xa8000000 -.long 0xa2f35151, 0x51000000, 0x5dfea3a3, 0xa3000000 -.long 0x80c04040, 0x40000000, 0x058a8f8f, 0x8f000000 -.long 0x3fad9292, 0x92000000, 0x21bc9d9d, 0x9d000000 -.long 0x70483838, 0x38000000, 0xf104f5f5, 0xf5000000 -.long 0x63dfbcbc, 0xbc000000, 0x77c1b6b6, 0xb6000000 -.long 0xaf75dada, 0xda000000, 0x42632121, 0x21000000 -.long 0x20301010, 0x10000000, 0xe51affff, 0xff000000 -.long 0xfd0ef3f3, 0xf3000000, 0xbf6dd2d2, 0xd2000000 -.long 0x814ccdcd, 0xcd000000, 0x18140c0c, 0x0c000000 -.long 0x26351313, 0x13000000, 0xc32fecec, 0xec000000 -.long 0xbee15f5f, 0x5f000000, 0x35a29797, 0x97000000 -.long 0x88cc4444, 0x44000000, 0x2e391717, 0x17000000 -.long 0x9357c4c4, 0xc4000000, 0x55f2a7a7, 0xa7000000 -.long 0xfc827e7e, 0x7e000000, 0x7a473d3d, 0x3d000000 -.long 0xc8ac6464, 0x64000000, 0xbae75d5d, 0x5d000000 -.long 0x322b1919, 0x19000000, 0xe6957373, 0x73000000 -.long 0xc0a06060, 0x60000000, 0x19988181, 0x81000000 -.long 0x9ed14f4f, 0x4f000000, 0xa37fdcdc, 0xdc000000 -.long 0x44662222, 0x22000000, 0x547e2a2a, 0x2a000000 -.long 0x3bab9090, 0x90000000, 0x0b838888, 0x88000000 -.long 0x8cca4646, 0x46000000, 0xc729eeee, 0xee000000 -.long 0x6bd3b8b8, 0xb8000000, 0x283c1414, 0x14000000 -.long 0xa779dede, 0xde000000, 0xbce25e5e, 0x5e000000 -.long 0x161d0b0b, 0x0b000000, 0xad76dbdb, 0xdb000000 -.long 0xdb3be0e0, 0xe0000000, 0x64563232, 0x32000000 -.long 0x744e3a3a, 0x3a000000, 0x141e0a0a, 0x0a000000 -.long 0x92db4949, 0x49000000, 0x0c0a0606, 0x06000000 -.long 0x486c2424, 0x24000000, 0xb8e45c5c, 0x5c000000 -.long 0x9f5dc2c2, 0xc2000000, 0xbd6ed3d3, 0xd3000000 -.long 0x43efacac, 0xac000000, 0xc4a66262, 0x62000000 -.long 0x39a89191, 0x91000000, 0x31a49595, 0x95000000 -.long 0xd337e4e4, 0xe4000000, 0xf28b7979, 0x79000000 -.long 0xd532e7e7, 0xe7000000, 0x8b43c8c8, 0xc8000000 -.long 0x6e593737, 0x37000000, 0xdab76d6d, 0x6d000000 -.long 0x018c8d8d, 0x8d000000, 0xb164d5d5, 0xd5000000 -.long 0x9cd24e4e, 0x4e000000, 0x49e0a9a9, 0xa9000000 -.long 0xd8b46c6c, 0x6c000000, 0xacfa5656, 0x56000000 -.long 0xf307f4f4, 0xf4000000, 0xcf25eaea, 0xea000000 -.long 0xcaaf6565, 0x65000000, 0xf48e7a7a, 0x7a000000 -.long 0x47e9aeae, 0xae000000, 0x10180808, 0x08000000 -.long 0x6fd5baba, 0xba000000, 0xf0887878, 0x78000000 -.long 0x4a6f2525, 0x25000000, 0x5c722e2e, 0x2e000000 -.long 0x38241c1c, 0x1c000000, 0x57f1a6a6, 0xa6000000 -.long 0x73c7b4b4, 0xb4000000, 0x9751c6c6, 0xc6000000 -.long 0xcb23e8e8, 0xe8000000, 0xa17cdddd, 0xdd000000 -.long 0xe89c7474, 0x74000000, 0x3e211f1f, 0x1f000000 -.long 0x96dd4b4b, 0x4b000000, 0x61dcbdbd, 0xbd000000 -.long 0x0d868b8b, 0x8b000000, 0x0f858a8a, 0x8a000000 -.long 0xe0907070, 0x70000000, 0x7c423e3e, 0x3e000000 -.long 0x71c4b5b5, 0xb5000000, 0xccaa6666, 0x66000000 -.long 0x90d84848, 0x48000000, 0x06050303, 0x03000000 -.long 0xf701f6f6, 0xf6000000, 0x1c120e0e, 0x0e000000 -.long 0xc2a36161, 0x61000000, 0x6a5f3535, 0x35000000 -.long 0xaef95757, 0x57000000, 0x69d0b9b9, 0xb9000000 -.long 0x17918686, 0x86000000, 0x9958c1c1, 0xc1000000 -.long 0x3a271d1d, 0x1d000000, 0x27b99e9e, 0x9e000000 -.long 0xd938e1e1, 0xe1000000, 0xeb13f8f8, 0xf8000000 -.long 0x2bb39898, 0x98000000, 0x22331111, 0x11000000 -.long 0xd2bb6969, 0x69000000, 0xa970d9d9, 0xd9000000 -.long 0x07898e8e, 0x8e000000, 0x33a79494, 0x94000000 -.long 0x2db69b9b, 0x9b000000, 0x3c221e1e, 0x1e000000 -.long 0x15928787, 0x87000000, 0xc920e9e9, 0xe9000000 -.long 0x8749cece, 0xce000000, 0xaaff5555, 0x55000000 -.long 0x50782828, 0x28000000, 0xa57adfdf, 0xdf000000 -.long 0x038f8c8c, 0x8c000000, 0x59f8a1a1, 0xa1000000 -.long 0x09808989, 0x89000000, 0x1a170d0d, 0x0d000000 -.long 0x65dabfbf, 0xbf000000, 0xd731e6e6, 0xe6000000 -.long 0x84c64242, 0x42000000, 0xd0b86868, 0x68000000 -.long 0x82c34141, 0x41000000, 0x29b09999, 0x99000000 -.long 0x5a772d2d, 0x2d000000, 0x1e110f0f, 0x0f000000 -.long 0x7bcbb0b0, 0xb0000000, 0xa8fc5454, 0x54000000 -.long 0x6dd6bbbb, 0xbb000000, 0x2c3a1616, 0x16000000 - -/* Decryption tables */ -.LtableD0: -.long 0x50a7f451 -.LtableDs0: -.long 0x00000052, 0x5365417e, 0x00000009 -.long 0xc3a4171a, 0x0000006a, 0x965e273a, 0x000000d5 -.long 0xcb6bab3b, 0x00000030, 0xf1459d1f, 0x00000036 -.long 0xab58faac, 0x000000a5, 0x9303e34b, 0x00000038 -.long 0x55fa3020, 0x000000bf, 0xf66d76ad, 0x00000040 -.long 0x9176cc88, 0x000000a3, 0x254c02f5, 0x0000009e -.long 0xfcd7e54f, 0x00000081, 0xd7cb2ac5, 0x000000f3 -.long 0x80443526, 0x000000d7, 0x8fa362b5, 0x000000fb -.long 0x495ab1de, 0x0000007c, 0x671bba25, 0x000000e3 -.long 0x980eea45, 0x00000039, 0xe1c0fe5d, 0x00000082 -.long 0x02752fc3, 0x0000009b, 0x12f04c81, 0x0000002f -.long 0xa397468d, 0x000000ff, 0xc6f9d36b, 0x00000087 -.long 0xe75f8f03, 0x00000034, 0x959c9215, 0x0000008e -.long 0xeb7a6dbf, 0x00000043, 0xda595295, 0x00000044 -.long 0x2d83bed4, 0x000000c4, 0xd3217458, 0x000000de -.long 0x2969e049, 0x000000e9, 0x44c8c98e, 0x000000cb -.long 0x6a89c275, 0x00000054, 0x78798ef4, 0x0000007b -.long 0x6b3e5899, 0x00000094, 0xdd71b927, 0x00000032 -.long 0xb64fe1be, 0x000000a6, 0x17ad88f0, 0x000000c2 -.long 0x66ac20c9, 0x00000023, 0xb43ace7d, 0x0000003d -.long 0x184adf63, 0x000000ee, 0x82311ae5, 0x0000004c -.long 0x60335197, 0x00000095, 0x457f5362, 0x0000000b -.long 0xe07764b1, 0x00000042, 0x84ae6bbb, 0x000000fa -.long 0x1ca081fe, 0x000000c3, 0x942b08f9, 0x0000004e -.long 0x58684870, 0x00000008, 0x19fd458f, 0x0000002e -.long 0x876cde94, 0x000000a1, 0xb7f87b52, 0x00000066 -.long 0x23d373ab, 0x00000028, 0xe2024b72, 0x000000d9 -.long 0x578f1fe3, 0x00000024, 0x2aab5566, 0x000000b2 -.long 0x0728ebb2, 0x00000076, 0x03c2b52f, 0x0000005b -.long 0x9a7bc586, 0x000000a2, 0xa50837d3, 0x00000049 -.long 0xf2872830, 0x0000006d, 0xb2a5bf23, 0x0000008b -.long 0xba6a0302, 0x000000d1, 0x5c8216ed, 0x00000025 -.long 0x2b1ccf8a, 0x00000072, 0x92b479a7, 0x000000f8 -.long 0xf0f207f3, 0x000000f6, 0xa1e2694e, 0x00000064 -.long 0xcdf4da65, 0x00000086, 0xd5be0506, 0x00000068 -.long 0x1f6234d1, 0x00000098, 0x8afea6c4, 0x00000016 -.long 0x9d532e34, 0x000000d4, 0xa055f3a2, 0x000000a4 -.long 0x32e18a05, 0x0000005c, 0x75ebf6a4, 0x000000cc -.long 0x39ec830b, 0x0000005d, 0xaaef6040, 0x00000065 -.long 0x069f715e, 0x000000b6, 0x51106ebd, 0x00000092 -.long 0xf98a213e, 0x0000006c, 0x3d06dd96, 0x00000070 -.long 0xae053edd, 0x00000048, 0x46bde64d, 0x00000050 -.long 0xb58d5491, 0x000000fd, 0x055dc471, 0x000000ed -.long 0x6fd40604, 0x000000b9, 0xff155060, 0x000000da -.long 0x24fb9819, 0x0000005e, 0x97e9bdd6, 0x00000015 -.long 0xcc434089, 0x00000046, 0x779ed967, 0x00000057 -.long 0xbd42e8b0, 0x000000a7, 0x888b8907, 0x0000008d -.long 0x385b19e7, 0x0000009d, 0xdbeec879, 0x00000084 -.long 0x470a7ca1, 0x00000090, 0xe90f427c, 0x000000d8 -.long 0xc91e84f8, 0x000000ab, 0x00000000, 0x00000000 -.long 0x83868009, 0x0000008c, 0x48ed2b32, 0x000000bc -.long 0xac70111e, 0x000000d3, 0x4e725a6c, 0x0000000a -.long 0xfbff0efd, 0x000000f7, 0x5638850f, 0x000000e4 -.long 0x1ed5ae3d, 0x00000058, 0x27392d36, 0x00000005 -.long 0x64d90f0a, 0x000000b8, 0x21a65c68, 0x000000b3 -.long 0xd1545b9b, 0x00000045, 0x3a2e3624, 0x00000006 -.long 0xb1670a0c, 0x000000d0, 0x0fe75793, 0x0000002c -.long 0xd296eeb4, 0x0000001e, 0x9e919b1b, 0x0000008f -.long 0x4fc5c080, 0x000000ca, 0xa220dc61, 0x0000003f -.long 0x694b775a, 0x0000000f, 0x161a121c, 0x00000002 -.long 0x0aba93e2, 0x000000c1, 0xe52aa0c0, 0x000000af -.long 0x43e0223c, 0x000000bd, 0x1d171b12, 0x00000003 -.long 0x0b0d090e, 0x00000001, 0xadc78bf2, 0x00000013 -.long 0xb9a8b62d, 0x0000008a, 0xc8a91e14, 0x0000006b -.long 0x8519f157, 0x0000003a, 0x4c0775af, 0x00000091 -.long 0xbbdd99ee, 0x00000011, 0xfd607fa3, 0x00000041 -.long 0x9f2601f7, 0x0000004f, 0xbcf5725c, 0x00000067 -.long 0xc53b6644, 0x000000dc, 0x347efb5b, 0x000000ea -.long 0x7629438b, 0x00000097, 0xdcc623cb, 0x000000f2 -.long 0x68fcedb6, 0x000000cf, 0x63f1e4b8, 0x000000ce -.long 0xcadc31d7, 0x000000f0, 0x10856342, 0x000000b4 -.long 0x40229713, 0x000000e6, 0x2011c684, 0x00000073 -.long 0x7d244a85, 0x00000096, 0xf83dbbd2, 0x000000ac -.long 0x1132f9ae, 0x00000074, 0x6da129c7, 0x00000022 -.long 0x4b2f9e1d, 0x000000e7, 0xf330b2dc, 0x000000ad -.long 0xec52860d, 0x00000035, 0xd0e3c177, 0x00000085 -.long 0x6c16b32b, 0x000000e2, 0x99b970a9, 0x000000f9 -.long 0xfa489411, 0x00000037, 0x2264e947, 0x000000e8 -.long 0xc48cfca8, 0x0000001c, 0x1a3ff0a0, 0x00000075 -.long 0xd82c7d56, 0x000000df, 0xef903322, 0x0000006e -.long 0xc74e4987, 0x00000047, 0xc1d138d9, 0x000000f1 -.long 0xfea2ca8c, 0x0000001a, 0x360bd498, 0x00000071 -.long 0xcf81f5a6, 0x0000001d, 0x28de7aa5, 0x00000029 -.long 0x268eb7da, 0x000000c5, 0xa4bfad3f, 0x00000089 -.long 0xe49d3a2c, 0x0000006f, 0x0d927850, 0x000000b7 -.long 0x9bcc5f6a, 0x00000062, 0x62467e54, 0x0000000e -.long 0xc2138df6, 0x000000aa, 0xe8b8d890, 0x00000018 -.long 0x5ef7392e, 0x000000be, 0xf5afc382, 0x0000001b -.long 0xbe805d9f, 0x000000fc, 0x7c93d069, 0x00000056 -.long 0xa92dd56f, 0x0000003e, 0xb31225cf, 0x0000004b -.long 0x3b99acc8, 0x000000c6, 0xa77d1810, 0x000000d2 -.long 0x6e639ce8, 0x00000079, 0x7bbb3bdb, 0x00000020 -.long 0x097826cd, 0x0000009a, 0xf418596e, 0x000000db -.long 0x01b79aec, 0x000000c0, 0xa89a4f83, 0x000000fe -.long 0x656e95e6, 0x00000078, 0x7ee6ffaa, 0x000000cd -.long 0x08cfbc21, 0x0000005a, 0xe6e815ef, 0x000000f4 -.long 0xd99be7ba, 0x0000001f, 0xce366f4a, 0x000000dd -.long 0xd4099fea, 0x000000a8, 0xd67cb029, 0x00000033 -.long 0xafb2a431, 0x00000088, 0x31233f2a, 0x00000007 -.long 0x3094a5c6, 0x000000c7, 0xc066a235, 0x00000031 -.long 0x37bc4e74, 0x000000b1, 0xa6ca82fc, 0x00000012 -.long 0xb0d090e0, 0x00000010, 0x15d8a733, 0x00000059 -.long 0x4a9804f1, 0x00000027, 0xf7daec41, 0x00000080 -.long 0x0e50cd7f, 0x000000ec, 0x2ff69117, 0x0000005f -.long 0x8dd64d76, 0x00000060, 0x4db0ef43, 0x00000051 -.long 0x544daacc, 0x0000007f, 0xdf0496e4, 0x000000a9 -.long 0xe3b5d19e, 0x00000019, 0x1b886a4c, 0x000000b5 -.long 0xb81f2cc1, 0x0000004a, 0x7f516546, 0x0000000d -.long 0x04ea5e9d, 0x0000002d, 0x5d358c01, 0x000000e5 -.long 0x737487fa, 0x0000007a, 0x2e410bfb, 0x0000009f -.long 0x5a1d67b3, 0x00000093, 0x52d2db92, 0x000000c9 -.long 0x335610e9, 0x0000009c, 0x1347d66d, 0x000000ef -.long 0x8c61d79a, 0x000000a0, 0x7a0ca137, 0x000000e0 -.long 0x8e14f859, 0x0000003b, 0x893c13eb, 0x0000004d -.long 0xee27a9ce, 0x000000ae, 0x35c961b7, 0x0000002a -.long 0xede51ce1, 0x000000f5, 0x3cb1477a, 0x000000b0 -.long 0x59dfd29c, 0x000000c8, 0x3f73f255, 0x000000eb -.long 0x79ce1418, 0x000000bb, 0xbf37c773, 0x0000003c -.long 0xeacdf753, 0x00000083, 0x5baafd5f, 0x00000053 -.long 0x146f3ddf, 0x00000099, 0x86db4478, 0x00000061 -.long 0x81f3afca, 0x00000017, 0x3ec468b9, 0x0000002b -.long 0x2c342438, 0x00000004, 0x5f40a3c2, 0x0000007e -.long 0x72c31d16, 0x000000ba, 0x0c25e2bc, 0x00000077 -.long 0x8b493c28, 0x000000d6, 0x41950dff, 0x00000026 -.long 0x7101a839, 0x000000e1, 0xdeb30c08, 0x00000069 -.long 0x9ce4b4d8, 0x00000014, 0x90c15664, 0x00000063 -.long 0x6184cb7b, 0x00000055, 0x70b632d5, 0x00000021 -.long 0x745c6c48, 0x0000000c, 0x4257b8d0, 0x0000007d -.LtableD1: -.long 0xa7f45150 -.LtableDs1: -.long 0x00005200, 0x65417e53, 0x00000900 -.long 0xa4171ac3, 0x00006a00, 0x5e273a96, 0x0000d500 -.long 0x6bab3bcb, 0x00003000, 0x459d1ff1, 0x00003600 -.long 0x58faacab, 0x0000a500, 0x03e34b93, 0x00003800 -.long 0xfa302055, 0x0000bf00, 0x6d76adf6, 0x00004000 -.long 0x76cc8891, 0x0000a300, 0x4c02f525, 0x00009e00 -.long 0xd7e54ffc, 0x00008100, 0xcb2ac5d7, 0x0000f300 -.long 0x44352680, 0x0000d700, 0xa362b58f, 0x0000fb00 -.long 0x5ab1de49, 0x00007c00, 0x1bba2567, 0x0000e300 -.long 0x0eea4598, 0x00003900, 0xc0fe5de1, 0x00008200 -.long 0x752fc302, 0x00009b00, 0xf04c8112, 0x00002f00 -.long 0x97468da3, 0x0000ff00, 0xf9d36bc6, 0x00008700 -.long 0x5f8f03e7, 0x00003400, 0x9c921595, 0x00008e00 -.long 0x7a6dbfeb, 0x00004300, 0x595295da, 0x00004400 -.long 0x83bed42d, 0x0000c400, 0x217458d3, 0x0000de00 -.long 0x69e04929, 0x0000e900, 0xc8c98e44, 0x0000cb00 -.long 0x89c2756a, 0x00005400, 0x798ef478, 0x00007b00 -.long 0x3e58996b, 0x00009400, 0x71b927dd, 0x00003200 -.long 0x4fe1beb6, 0x0000a600, 0xad88f017, 0x0000c200 -.long 0xac20c966, 0x00002300, 0x3ace7db4, 0x00003d00 -.long 0x4adf6318, 0x0000ee00, 0x311ae582, 0x00004c00 -.long 0x33519760, 0x00009500, 0x7f536245, 0x00000b00 -.long 0x7764b1e0, 0x00004200, 0xae6bbb84, 0x0000fa00 -.long 0xa081fe1c, 0x0000c300, 0x2b08f994, 0x00004e00 -.long 0x68487058, 0x00000800, 0xfd458f19, 0x00002e00 -.long 0x6cde9487, 0x0000a100, 0xf87b52b7, 0x00006600 -.long 0xd373ab23, 0x00002800, 0x024b72e2, 0x0000d900 -.long 0x8f1fe357, 0x00002400, 0xab55662a, 0x0000b200 -.long 0x28ebb207, 0x00007600, 0xc2b52f03, 0x00005b00 -.long 0x7bc5869a, 0x0000a200, 0x0837d3a5, 0x00004900 -.long 0x872830f2, 0x00006d00, 0xa5bf23b2, 0x00008b00 -.long 0x6a0302ba, 0x0000d100, 0x8216ed5c, 0x00002500 -.long 0x1ccf8a2b, 0x00007200, 0xb479a792, 0x0000f800 -.long 0xf207f3f0, 0x0000f600, 0xe2694ea1, 0x00006400 -.long 0xf4da65cd, 0x00008600, 0xbe0506d5, 0x00006800 -.long 0x6234d11f, 0x00009800, 0xfea6c48a, 0x00001600 -.long 0x532e349d, 0x0000d400, 0x55f3a2a0, 0x0000a400 -.long 0xe18a0532, 0x00005c00, 0xebf6a475, 0x0000cc00 -.long 0xec830b39, 0x00005d00, 0xef6040aa, 0x00006500 -.long 0x9f715e06, 0x0000b600, 0x106ebd51, 0x00009200 -.long 0x8a213ef9, 0x00006c00, 0x06dd963d, 0x00007000 -.long 0x053eddae, 0x00004800, 0xbde64d46, 0x00005000 -.long 0x8d5491b5, 0x0000fd00, 0x5dc47105, 0x0000ed00 -.long 0xd406046f, 0x0000b900, 0x155060ff, 0x0000da00 -.long 0xfb981924, 0x00005e00, 0xe9bdd697, 0x00001500 -.long 0x434089cc, 0x00004600, 0x9ed96777, 0x00005700 -.long 0x42e8b0bd, 0x0000a700, 0x8b890788, 0x00008d00 -.long 0x5b19e738, 0x00009d00, 0xeec879db, 0x00008400 -.long 0x0a7ca147, 0x00009000, 0x0f427ce9, 0x0000d800 -.long 0x1e84f8c9, 0x0000ab00, 0x00000000, 0x00000000 -.long 0x86800983, 0x00008c00, 0xed2b3248, 0x0000bc00 -.long 0x70111eac, 0x0000d300, 0x725a6c4e, 0x00000a00 -.long 0xff0efdfb, 0x0000f700, 0x38850f56, 0x0000e400 -.long 0xd5ae3d1e, 0x00005800, 0x392d3627, 0x00000500 -.long 0xd90f0a64, 0x0000b800, 0xa65c6821, 0x0000b300 -.long 0x545b9bd1, 0x00004500, 0x2e36243a, 0x00000600 -.long 0x670a0cb1, 0x0000d000, 0xe757930f, 0x00002c00 -.long 0x96eeb4d2, 0x00001e00, 0x919b1b9e, 0x00008f00 -.long 0xc5c0804f, 0x0000ca00, 0x20dc61a2, 0x00003f00 -.long 0x4b775a69, 0x00000f00, 0x1a121c16, 0x00000200 -.long 0xba93e20a, 0x0000c100, 0x2aa0c0e5, 0x0000af00 -.long 0xe0223c43, 0x0000bd00, 0x171b121d, 0x00000300 -.long 0x0d090e0b, 0x00000100, 0xc78bf2ad, 0x00001300 -.long 0xa8b62db9, 0x00008a00, 0xa91e14c8, 0x00006b00 -.long 0x19f15785, 0x00003a00, 0x0775af4c, 0x00009100 -.long 0xdd99eebb, 0x00001100, 0x607fa3fd, 0x00004100 -.long 0x2601f79f, 0x00004f00, 0xf5725cbc, 0x00006700 -.long 0x3b6644c5, 0x0000dc00, 0x7efb5b34, 0x0000ea00 -.long 0x29438b76, 0x00009700, 0xc623cbdc, 0x0000f200 -.long 0xfcedb668, 0x0000cf00, 0xf1e4b863, 0x0000ce00 -.long 0xdc31d7ca, 0x0000f000, 0x85634210, 0x0000b400 -.long 0x22971340, 0x0000e600, 0x11c68420, 0x00007300 -.long 0x244a857d, 0x00009600, 0x3dbbd2f8, 0x0000ac00 -.long 0x32f9ae11, 0x00007400, 0xa129c76d, 0x00002200 -.long 0x2f9e1d4b, 0x0000e700, 0x30b2dcf3, 0x0000ad00 -.long 0x52860dec, 0x00003500, 0xe3c177d0, 0x00008500 -.long 0x16b32b6c, 0x0000e200, 0xb970a999, 0x0000f900 -.long 0x489411fa, 0x00003700, 0x64e94722, 0x0000e800 -.long 0x8cfca8c4, 0x00001c00, 0x3ff0a01a, 0x00007500 -.long 0x2c7d56d8, 0x0000df00, 0x903322ef, 0x00006e00 -.long 0x4e4987c7, 0x00004700, 0xd138d9c1, 0x0000f100 -.long 0xa2ca8cfe, 0x00001a00, 0x0bd49836, 0x00007100 -.long 0x81f5a6cf, 0x00001d00, 0xde7aa528, 0x00002900 -.long 0x8eb7da26, 0x0000c500, 0xbfad3fa4, 0x00008900 -.long 0x9d3a2ce4, 0x00006f00, 0x9278500d, 0x0000b700 -.long 0xcc5f6a9b, 0x00006200, 0x467e5462, 0x00000e00 -.long 0x138df6c2, 0x0000aa00, 0xb8d890e8, 0x00001800 -.long 0xf7392e5e, 0x0000be00, 0xafc382f5, 0x00001b00 -.long 0x805d9fbe, 0x0000fc00, 0x93d0697c, 0x00005600 -.long 0x2dd56fa9, 0x00003e00, 0x1225cfb3, 0x00004b00 -.long 0x99acc83b, 0x0000c600, 0x7d1810a7, 0x0000d200 -.long 0x639ce86e, 0x00007900, 0xbb3bdb7b, 0x00002000 -.long 0x7826cd09, 0x00009a00, 0x18596ef4, 0x0000db00 -.long 0xb79aec01, 0x0000c000, 0x9a4f83a8, 0x0000fe00 -.long 0x6e95e665, 0x00007800, 0xe6ffaa7e, 0x0000cd00 -.long 0xcfbc2108, 0x00005a00, 0xe815efe6, 0x0000f400 -.long 0x9be7bad9, 0x00001f00, 0x366f4ace, 0x0000dd00 -.long 0x099fead4, 0x0000a800, 0x7cb029d6, 0x00003300 -.long 0xb2a431af, 0x00008800, 0x233f2a31, 0x00000700 -.long 0x94a5c630, 0x0000c700, 0x66a235c0, 0x00003100 -.long 0xbc4e7437, 0x0000b100, 0xca82fca6, 0x00001200 -.long 0xd090e0b0, 0x00001000, 0xd8a73315, 0x00005900 -.long 0x9804f14a, 0x00002700, 0xdaec41f7, 0x00008000 -.long 0x50cd7f0e, 0x0000ec00, 0xf691172f, 0x00005f00 -.long 0xd64d768d, 0x00006000, 0xb0ef434d, 0x00005100 -.long 0x4daacc54, 0x00007f00, 0x0496e4df, 0x0000a900 -.long 0xb5d19ee3, 0x00001900, 0x886a4c1b, 0x0000b500 -.long 0x1f2cc1b8, 0x00004a00, 0x5165467f, 0x00000d00 -.long 0xea5e9d04, 0x00002d00, 0x358c015d, 0x0000e500 -.long 0x7487fa73, 0x00007a00, 0x410bfb2e, 0x00009f00 -.long 0x1d67b35a, 0x00009300, 0xd2db9252, 0x0000c900 -.long 0x5610e933, 0x00009c00, 0x47d66d13, 0x0000ef00 -.long 0x61d79a8c, 0x0000a000, 0x0ca1377a, 0x0000e000 -.long 0x14f8598e, 0x00003b00, 0x3c13eb89, 0x00004d00 -.long 0x27a9ceee, 0x0000ae00, 0xc961b735, 0x00002a00 -.long 0xe51ce1ed, 0x0000f500, 0xb1477a3c, 0x0000b000 -.long 0xdfd29c59, 0x0000c800, 0x73f2553f, 0x0000eb00 -.long 0xce141879, 0x0000bb00, 0x37c773bf, 0x00003c00 -.long 0xcdf753ea, 0x00008300, 0xaafd5f5b, 0x00005300 -.long 0x6f3ddf14, 0x00009900, 0xdb447886, 0x00006100 -.long 0xf3afca81, 0x00001700, 0xc468b93e, 0x00002b00 -.long 0x3424382c, 0x00000400, 0x40a3c25f, 0x00007e00 -.long 0xc31d1672, 0x0000ba00, 0x25e2bc0c, 0x00007700 -.long 0x493c288b, 0x0000d600, 0x950dff41, 0x00002600 -.long 0x01a83971, 0x0000e100, 0xb30c08de, 0x00006900 -.long 0xe4b4d89c, 0x00001400, 0xc1566490, 0x00006300 -.long 0x84cb7b61, 0x00005500, 0xb632d570, 0x00002100 -.long 0x5c6c4874, 0x00000c00, 0x57b8d042, 0x00007d00 -.LtableD2: -.long 0xf45150a7 -.LtableDs2: -.long 0x00520000, 0x417e5365, 0x00090000 -.long 0x171ac3a4, 0x006a0000, 0x273a965e, 0x00d50000 -.long 0xab3bcb6b, 0x00300000, 0x9d1ff145, 0x00360000 -.long 0xfaacab58, 0x00a50000, 0xe34b9303, 0x00380000 -.long 0x302055fa, 0x00bf0000, 0x76adf66d, 0x00400000 -.long 0xcc889176, 0x00a30000, 0x02f5254c, 0x009e0000 -.long 0xe54ffcd7, 0x00810000, 0x2ac5d7cb, 0x00f30000 -.long 0x35268044, 0x00d70000, 0x62b58fa3, 0x00fb0000 -.long 0xb1de495a, 0x007c0000, 0xba25671b, 0x00e30000 -.long 0xea45980e, 0x00390000, 0xfe5de1c0, 0x00820000 -.long 0x2fc30275, 0x009b0000, 0x4c8112f0, 0x002f0000 -.long 0x468da397, 0x00ff0000, 0xd36bc6f9, 0x00870000 -.long 0x8f03e75f, 0x00340000, 0x9215959c, 0x008e0000 -.long 0x6dbfeb7a, 0x00430000, 0x5295da59, 0x00440000 -.long 0xbed42d83, 0x00c40000, 0x7458d321, 0x00de0000 -.long 0xe0492969, 0x00e90000, 0xc98e44c8, 0x00cb0000 -.long 0xc2756a89, 0x00540000, 0x8ef47879, 0x007b0000 -.long 0x58996b3e, 0x00940000, 0xb927dd71, 0x00320000 -.long 0xe1beb64f, 0x00a60000, 0x88f017ad, 0x00c20000 -.long 0x20c966ac, 0x00230000, 0xce7db43a, 0x003d0000 -.long 0xdf63184a, 0x00ee0000, 0x1ae58231, 0x004c0000 -.long 0x51976033, 0x00950000, 0x5362457f, 0x000b0000 -.long 0x64b1e077, 0x00420000, 0x6bbb84ae, 0x00fa0000 -.long 0x81fe1ca0, 0x00c30000, 0x08f9942b, 0x004e0000 -.long 0x48705868, 0x00080000, 0x458f19fd, 0x002e0000 -.long 0xde94876c, 0x00a10000, 0x7b52b7f8, 0x00660000 -.long 0x73ab23d3, 0x00280000, 0x4b72e202, 0x00d90000 -.long 0x1fe3578f, 0x00240000, 0x55662aab, 0x00b20000 -.long 0xebb20728, 0x00760000, 0xb52f03c2, 0x005b0000 -.long 0xc5869a7b, 0x00a20000, 0x37d3a508, 0x00490000 -.long 0x2830f287, 0x006d0000, 0xbf23b2a5, 0x008b0000 -.long 0x0302ba6a, 0x00d10000, 0x16ed5c82, 0x00250000 -.long 0xcf8a2b1c, 0x00720000, 0x79a792b4, 0x00f80000 -.long 0x07f3f0f2, 0x00f60000, 0x694ea1e2, 0x00640000 -.long 0xda65cdf4, 0x00860000, 0x0506d5be, 0x00680000 -.long 0x34d11f62, 0x00980000, 0xa6c48afe, 0x00160000 -.long 0x2e349d53, 0x00d40000, 0xf3a2a055, 0x00a40000 -.long 0x8a0532e1, 0x005c0000, 0xf6a475eb, 0x00cc0000 -.long 0x830b39ec, 0x005d0000, 0x6040aaef, 0x00650000 -.long 0x715e069f, 0x00b60000, 0x6ebd5110, 0x00920000 -.long 0x213ef98a, 0x006c0000, 0xdd963d06, 0x00700000 -.long 0x3eddae05, 0x00480000, 0xe64d46bd, 0x00500000 -.long 0x5491b58d, 0x00fd0000, 0xc471055d, 0x00ed0000 -.long 0x06046fd4, 0x00b90000, 0x5060ff15, 0x00da0000 -.long 0x981924fb, 0x005e0000, 0xbdd697e9, 0x00150000 -.long 0x4089cc43, 0x00460000, 0xd967779e, 0x00570000 -.long 0xe8b0bd42, 0x00a70000, 0x8907888b, 0x008d0000 -.long 0x19e7385b, 0x009d0000, 0xc879dbee, 0x00840000 -.long 0x7ca1470a, 0x00900000, 0x427ce90f, 0x00d80000 -.long 0x84f8c91e, 0x00ab0000, 0x00000000, 0x00000000 -.long 0x80098386, 0x008c0000, 0x2b3248ed, 0x00bc0000 -.long 0x111eac70, 0x00d30000, 0x5a6c4e72, 0x000a0000 -.long 0x0efdfbff, 0x00f70000, 0x850f5638, 0x00e40000 -.long 0xae3d1ed5, 0x00580000, 0x2d362739, 0x00050000 -.long 0x0f0a64d9, 0x00b80000, 0x5c6821a6, 0x00b30000 -.long 0x5b9bd154, 0x00450000, 0x36243a2e, 0x00060000 -.long 0x0a0cb167, 0x00d00000, 0x57930fe7, 0x002c0000 -.long 0xeeb4d296, 0x001e0000, 0x9b1b9e91, 0x008f0000 -.long 0xc0804fc5, 0x00ca0000, 0xdc61a220, 0x003f0000 -.long 0x775a694b, 0x000f0000, 0x121c161a, 0x00020000 -.long 0x93e20aba, 0x00c10000, 0xa0c0e52a, 0x00af0000 -.long 0x223c43e0, 0x00bd0000, 0x1b121d17, 0x00030000 -.long 0x090e0b0d, 0x00010000, 0x8bf2adc7, 0x00130000 -.long 0xb62db9a8, 0x008a0000, 0x1e14c8a9, 0x006b0000 -.long 0xf1578519, 0x003a0000, 0x75af4c07, 0x00910000 -.long 0x99eebbdd, 0x00110000, 0x7fa3fd60, 0x00410000 -.long 0x01f79f26, 0x004f0000, 0x725cbcf5, 0x00670000 -.long 0x6644c53b, 0x00dc0000, 0xfb5b347e, 0x00ea0000 -.long 0x438b7629, 0x00970000, 0x23cbdcc6, 0x00f20000 -.long 0xedb668fc, 0x00cf0000, 0xe4b863f1, 0x00ce0000 -.long 0x31d7cadc, 0x00f00000, 0x63421085, 0x00b40000 -.long 0x97134022, 0x00e60000, 0xc6842011, 0x00730000 -.long 0x4a857d24, 0x00960000, 0xbbd2f83d, 0x00ac0000 -.long 0xf9ae1132, 0x00740000, 0x29c76da1, 0x00220000 -.long 0x9e1d4b2f, 0x00e70000, 0xb2dcf330, 0x00ad0000 -.long 0x860dec52, 0x00350000, 0xc177d0e3, 0x00850000 -.long 0xb32b6c16, 0x00e20000, 0x70a999b9, 0x00f90000 -.long 0x9411fa48, 0x00370000, 0xe9472264, 0x00e80000 -.long 0xfca8c48c, 0x001c0000, 0xf0a01a3f, 0x00750000 -.long 0x7d56d82c, 0x00df0000, 0x3322ef90, 0x006e0000 -.long 0x4987c74e, 0x00470000, 0x38d9c1d1, 0x00f10000 -.long 0xca8cfea2, 0x001a0000, 0xd498360b, 0x00710000 -.long 0xf5a6cf81, 0x001d0000, 0x7aa528de, 0x00290000 -.long 0xb7da268e, 0x00c50000, 0xad3fa4bf, 0x00890000 -.long 0x3a2ce49d, 0x006f0000, 0x78500d92, 0x00b70000 -.long 0x5f6a9bcc, 0x00620000, 0x7e546246, 0x000e0000 -.long 0x8df6c213, 0x00aa0000, 0xd890e8b8, 0x00180000 -.long 0x392e5ef7, 0x00be0000, 0xc382f5af, 0x001b0000 -.long 0x5d9fbe80, 0x00fc0000, 0xd0697c93, 0x00560000 -.long 0xd56fa92d, 0x003e0000, 0x25cfb312, 0x004b0000 -.long 0xacc83b99, 0x00c60000, 0x1810a77d, 0x00d20000 -.long 0x9ce86e63, 0x00790000, 0x3bdb7bbb, 0x00200000 -.long 0x26cd0978, 0x009a0000, 0x596ef418, 0x00db0000 -.long 0x9aec01b7, 0x00c00000, 0x4f83a89a, 0x00fe0000 -.long 0x95e6656e, 0x00780000, 0xffaa7ee6, 0x00cd0000 -.long 0xbc2108cf, 0x005a0000, 0x15efe6e8, 0x00f40000 -.long 0xe7bad99b, 0x001f0000, 0x6f4ace36, 0x00dd0000 -.long 0x9fead409, 0x00a80000, 0xb029d67c, 0x00330000 -.long 0xa431afb2, 0x00880000, 0x3f2a3123, 0x00070000 -.long 0xa5c63094, 0x00c70000, 0xa235c066, 0x00310000 -.long 0x4e7437bc, 0x00b10000, 0x82fca6ca, 0x00120000 -.long 0x90e0b0d0, 0x00100000, 0xa73315d8, 0x00590000 -.long 0x04f14a98, 0x00270000, 0xec41f7da, 0x00800000 -.long 0xcd7f0e50, 0x00ec0000, 0x91172ff6, 0x005f0000 -.long 0x4d768dd6, 0x00600000, 0xef434db0, 0x00510000 -.long 0xaacc544d, 0x007f0000, 0x96e4df04, 0x00a90000 -.long 0xd19ee3b5, 0x00190000, 0x6a4c1b88, 0x00b50000 -.long 0x2cc1b81f, 0x004a0000, 0x65467f51, 0x000d0000 -.long 0x5e9d04ea, 0x002d0000, 0x8c015d35, 0x00e50000 -.long 0x87fa7374, 0x007a0000, 0x0bfb2e41, 0x009f0000 -.long 0x67b35a1d, 0x00930000, 0xdb9252d2, 0x00c90000 -.long 0x10e93356, 0x009c0000, 0xd66d1347, 0x00ef0000 -.long 0xd79a8c61, 0x00a00000, 0xa1377a0c, 0x00e00000 -.long 0xf8598e14, 0x003b0000, 0x13eb893c, 0x004d0000 -.long 0xa9ceee27, 0x00ae0000, 0x61b735c9, 0x002a0000 -.long 0x1ce1ede5, 0x00f50000, 0x477a3cb1, 0x00b00000 -.long 0xd29c59df, 0x00c80000, 0xf2553f73, 0x00eb0000 -.long 0x141879ce, 0x00bb0000, 0xc773bf37, 0x003c0000 -.long 0xf753eacd, 0x00830000, 0xfd5f5baa, 0x00530000 -.long 0x3ddf146f, 0x00990000, 0x447886db, 0x00610000 -.long 0xafca81f3, 0x00170000, 0x68b93ec4, 0x002b0000 -.long 0x24382c34, 0x00040000, 0xa3c25f40, 0x007e0000 -.long 0x1d1672c3, 0x00ba0000, 0xe2bc0c25, 0x00770000 -.long 0x3c288b49, 0x00d60000, 0x0dff4195, 0x00260000 -.long 0xa8397101, 0x00e10000, 0x0c08deb3, 0x00690000 -.long 0xb4d89ce4, 0x00140000, 0x566490c1, 0x00630000 -.long 0xcb7b6184, 0x00550000, 0x32d570b6, 0x00210000 -.long 0x6c48745c, 0x000c0000, 0xb8d04257, 0x007d0000 -.LtableD3: -.long 0x5150a7f4 -.LtableDs3: -.long 0x52000000, 0x7e536541, 0x09000000 -.long 0x1ac3a417, 0x6a000000, 0x3a965e27, 0xd5000000 -.long 0x3bcb6bab, 0x30000000, 0x1ff1459d, 0x36000000 -.long 0xacab58fa, 0xa5000000, 0x4b9303e3, 0x38000000 -.long 0x2055fa30, 0xbf000000, 0xadf66d76, 0x40000000 -.long 0x889176cc, 0xa3000000, 0xf5254c02, 0x9e000000 -.long 0x4ffcd7e5, 0x81000000, 0xc5d7cb2a, 0xf3000000 -.long 0x26804435, 0xd7000000, 0xb58fa362, 0xfb000000 -.long 0xde495ab1, 0x7c000000, 0x25671bba, 0xe3000000 -.long 0x45980eea, 0x39000000, 0x5de1c0fe, 0x82000000 -.long 0xc302752f, 0x9b000000, 0x8112f04c, 0x2f000000 -.long 0x8da39746, 0xff000000, 0x6bc6f9d3, 0x87000000 -.long 0x03e75f8f, 0x34000000, 0x15959c92, 0x8e000000 -.long 0xbfeb7a6d, 0x43000000, 0x95da5952, 0x44000000 -.long 0xd42d83be, 0xc4000000, 0x58d32174, 0xde000000 -.long 0x492969e0, 0xe9000000, 0x8e44c8c9, 0xcb000000 -.long 0x756a89c2, 0x54000000, 0xf478798e, 0x7b000000 -.long 0x996b3e58, 0x94000000, 0x27dd71b9, 0x32000000 -.long 0xbeb64fe1, 0xa6000000, 0xf017ad88, 0xc2000000 -.long 0xc966ac20, 0x23000000, 0x7db43ace, 0x3d000000 -.long 0x63184adf, 0xee000000, 0xe582311a, 0x4c000000 -.long 0x97603351, 0x95000000, 0x62457f53, 0x0b000000 -.long 0xb1e07764, 0x42000000, 0xbb84ae6b, 0xfa000000 -.long 0xfe1ca081, 0xc3000000, 0xf9942b08, 0x4e000000 -.long 0x70586848, 0x08000000, 0x8f19fd45, 0x2e000000 -.long 0x94876cde, 0xa1000000, 0x52b7f87b, 0x66000000 -.long 0xab23d373, 0x28000000, 0x72e2024b, 0xd9000000 -.long 0xe3578f1f, 0x24000000, 0x662aab55, 0xb2000000 -.long 0xb20728eb, 0x76000000, 0x2f03c2b5, 0x5b000000 -.long 0x869a7bc5, 0xa2000000, 0xd3a50837, 0x49000000 -.long 0x30f28728, 0x6d000000, 0x23b2a5bf, 0x8b000000 -.long 0x02ba6a03, 0xd1000000, 0xed5c8216, 0x25000000 -.long 0x8a2b1ccf, 0x72000000, 0xa792b479, 0xf8000000 -.long 0xf3f0f207, 0xf6000000, 0x4ea1e269, 0x64000000 -.long 0x65cdf4da, 0x86000000, 0x06d5be05, 0x68000000 -.long 0xd11f6234, 0x98000000, 0xc48afea6, 0x16000000 -.long 0x349d532e, 0xd4000000, 0xa2a055f3, 0xa4000000 -.long 0x0532e18a, 0x5c000000, 0xa475ebf6, 0xcc000000 -.long 0x0b39ec83, 0x5d000000, 0x40aaef60, 0x65000000 -.long 0x5e069f71, 0xb6000000, 0xbd51106e, 0x92000000 -.long 0x3ef98a21, 0x6c000000, 0x963d06dd, 0x70000000 -.long 0xddae053e, 0x48000000, 0x4d46bde6, 0x50000000 -.long 0x91b58d54, 0xfd000000, 0x71055dc4, 0xed000000 -.long 0x046fd406, 0xb9000000, 0x60ff1550, 0xda000000 -.long 0x1924fb98, 0x5e000000, 0xd697e9bd, 0x15000000 -.long 0x89cc4340, 0x46000000, 0x67779ed9, 0x57000000 -.long 0xb0bd42e8, 0xa7000000, 0x07888b89, 0x8d000000 -.long 0xe7385b19, 0x9d000000, 0x79dbeec8, 0x84000000 -.long 0xa1470a7c, 0x90000000, 0x7ce90f42, 0xd8000000 -.long 0xf8c91e84, 0xab000000, 0x00000000, 0x00000000 -.long 0x09838680, 0x8c000000, 0x3248ed2b, 0xbc000000 -.long 0x1eac7011, 0xd3000000, 0x6c4e725a, 0x0a000000 -.long 0xfdfbff0e, 0xf7000000, 0x0f563885, 0xe4000000 -.long 0x3d1ed5ae, 0x58000000, 0x3627392d, 0x05000000 -.long 0x0a64d90f, 0xb8000000, 0x6821a65c, 0xb3000000 -.long 0x9bd1545b, 0x45000000, 0x243a2e36, 0x06000000 -.long 0x0cb1670a, 0xd0000000, 0x930fe757, 0x2c000000 -.long 0xb4d296ee, 0x1e000000, 0x1b9e919b, 0x8f000000 -.long 0x804fc5c0, 0xca000000, 0x61a220dc, 0x3f000000 -.long 0x5a694b77, 0x0f000000, 0x1c161a12, 0x02000000 -.long 0xe20aba93, 0xc1000000, 0xc0e52aa0, 0xaf000000 -.long 0x3c43e022, 0xbd000000, 0x121d171b, 0x03000000 -.long 0x0e0b0d09, 0x01000000, 0xf2adc78b, 0x13000000 -.long 0x2db9a8b6, 0x8a000000, 0x14c8a91e, 0x6b000000 -.long 0x578519f1, 0x3a000000, 0xaf4c0775, 0x91000000 -.long 0xeebbdd99, 0x11000000, 0xa3fd607f, 0x41000000 -.long 0xf79f2601, 0x4f000000, 0x5cbcf572, 0x67000000 -.long 0x44c53b66, 0xdc000000, 0x5b347efb, 0xea000000 -.long 0x8b762943, 0x97000000, 0xcbdcc623, 0xf2000000 -.long 0xb668fced, 0xcf000000, 0xb863f1e4, 0xce000000 -.long 0xd7cadc31, 0xf0000000, 0x42108563, 0xb4000000 -.long 0x13402297, 0xe6000000, 0x842011c6, 0x73000000 -.long 0x857d244a, 0x96000000, 0xd2f83dbb, 0xac000000 -.long 0xae1132f9, 0x74000000, 0xc76da129, 0x22000000 -.long 0x1d4b2f9e, 0xe7000000, 0xdcf330b2, 0xad000000 -.long 0x0dec5286, 0x35000000, 0x77d0e3c1, 0x85000000 -.long 0x2b6c16b3, 0xe2000000, 0xa999b970, 0xf9000000 -.long 0x11fa4894, 0x37000000, 0x472264e9, 0xe8000000 -.long 0xa8c48cfc, 0x1c000000, 0xa01a3ff0, 0x75000000 -.long 0x56d82c7d, 0xdf000000, 0x22ef9033, 0x6e000000 -.long 0x87c74e49, 0x47000000, 0xd9c1d138, 0xf1000000 -.long 0x8cfea2ca, 0x1a000000, 0x98360bd4, 0x71000000 -.long 0xa6cf81f5, 0x1d000000, 0xa528de7a, 0x29000000 -.long 0xda268eb7, 0xc5000000, 0x3fa4bfad, 0x89000000 -.long 0x2ce49d3a, 0x6f000000, 0x500d9278, 0xb7000000 -.long 0x6a9bcc5f, 0x62000000, 0x5462467e, 0x0e000000 -.long 0xf6c2138d, 0xaa000000, 0x90e8b8d8, 0x18000000 -.long 0x2e5ef739, 0xbe000000, 0x82f5afc3, 0x1b000000 -.long 0x9fbe805d, 0xfc000000, 0x697c93d0, 0x56000000 -.long 0x6fa92dd5, 0x3e000000, 0xcfb31225, 0x4b000000 -.long 0xc83b99ac, 0xc6000000, 0x10a77d18, 0xd2000000 -.long 0xe86e639c, 0x79000000, 0xdb7bbb3b, 0x20000000 -.long 0xcd097826, 0x9a000000, 0x6ef41859, 0xdb000000 -.long 0xec01b79a, 0xc0000000, 0x83a89a4f, 0xfe000000 -.long 0xe6656e95, 0x78000000, 0xaa7ee6ff, 0xcd000000 -.long 0x2108cfbc, 0x5a000000, 0xefe6e815, 0xf4000000 -.long 0xbad99be7, 0x1f000000, 0x4ace366f, 0xdd000000 -.long 0xead4099f, 0xa8000000, 0x29d67cb0, 0x33000000 -.long 0x31afb2a4, 0x88000000, 0x2a31233f, 0x07000000 -.long 0xc63094a5, 0xc7000000, 0x35c066a2, 0x31000000 -.long 0x7437bc4e, 0xb1000000, 0xfca6ca82, 0x12000000 -.long 0xe0b0d090, 0x10000000, 0x3315d8a7, 0x59000000 -.long 0xf14a9804, 0x27000000, 0x41f7daec, 0x80000000 -.long 0x7f0e50cd, 0xec000000, 0x172ff691, 0x5f000000 -.long 0x768dd64d, 0x60000000, 0x434db0ef, 0x51000000 -.long 0xcc544daa, 0x7f000000, 0xe4df0496, 0xa9000000 -.long 0x9ee3b5d1, 0x19000000, 0x4c1b886a, 0xb5000000 -.long 0xc1b81f2c, 0x4a000000, 0x467f5165, 0x0d000000 -.long 0x9d04ea5e, 0x2d000000, 0x015d358c, 0xe5000000 -.long 0xfa737487, 0x7a000000, 0xfb2e410b, 0x9f000000 -.long 0xb35a1d67, 0x93000000, 0x9252d2db, 0xc9000000 -.long 0xe9335610, 0x9c000000, 0x6d1347d6, 0xef000000 -.long 0x9a8c61d7, 0xa0000000, 0x377a0ca1, 0xe0000000 -.long 0x598e14f8, 0x3b000000, 0xeb893c13, 0x4d000000 -.long 0xceee27a9, 0xae000000, 0xb735c961, 0x2a000000 -.long 0xe1ede51c, 0xf5000000, 0x7a3cb147, 0xb0000000 -.long 0x9c59dfd2, 0xc8000000, 0x553f73f2, 0xeb000000 -.long 0x1879ce14, 0xbb000000, 0x73bf37c7, 0x3c000000 -.long 0x53eacdf7, 0x83000000, 0x5f5baafd, 0x53000000 -.long 0xdf146f3d, 0x99000000, 0x7886db44, 0x61000000 -.long 0xca81f3af, 0x17000000, 0xb93ec468, 0x2b000000 -.long 0x382c3424, 0x04000000, 0xc25f40a3, 0x7e000000 -.long 0x1672c31d, 0xba000000, 0xbc0c25e2, 0x77000000 -.long 0x288b493c, 0xd6000000, 0xff41950d, 0x26000000 -.long 0x397101a8, 0xe1000000, 0x08deb30c, 0x69000000 -.long 0xd89ce4b4, 0x14000000, 0x6490c156, 0x63000000 -.long 0x7b6184cb, 0x55000000, 0xd570b632, 0x21000000 -.long 0x48745c6c, 0x0c000000, 0xd04257b8, 0x7d000000 - #endif /*USE_AES*/ #endif /*__x86_64*/ diff --git a/cipher/rijndael-arm.S b/cipher/rijndael-arm.S index c385e67..e296684 100644 --- a/cipher/rijndael-arm.S +++ b/cipher/rijndael-arm.S @@ -28,19 +28,6 @@ .syntax unified .arm -#ifdef __PIC__ -# define GET_DATA_POINTER(reg, name, rtmp) \ - ldr reg, 1f; \ - ldr rtmp, 2f; \ - b 3f; \ - 1: .word _GLOBAL_OFFSET_TABLE_-(3f+8); \ - 2: .word name(GOT); \ - 3: add reg, pc, reg; \ - ldr reg, [reg, rtmp]; -#else -# define GET_DATA_POINTER(reg, name, rtmp) ldr reg, =name -#endif - /* register macros */ #define CTX %r0 #define RTAB %lr @@ -233,6 +220,7 @@ _gcry_aes_arm_encrypt_block: * %r1: dst * %r2: src * %r3: number of rounds.. 10, 12 or 14 + * %st+0: encryption table */ push {%r4-%r11, %ip, %lr}; @@ -260,10 +248,9 @@ _gcry_aes_arm_encrypt_block: rev RD, RD; #endif 2: + ldr RTAB, [%sp, #40]; sub %sp, #16; - GET_DATA_POINTER(RTAB, .LtableE0, RMASK); - str %r1, [%sp, #4]; /* dst */ mov RMASK, #0xff; str %r3, [%sp, #8]; /* nrounds */ @@ -489,6 +476,7 @@ _gcry_aes_arm_decrypt_block: * %r1: dst * %r2: src * %r3: number of rounds.. 10, 12 or 14 + * %st+0: decryption table */ push {%r4-%r11, %ip, %lr}; @@ -516,10 +504,9 @@ _gcry_aes_arm_decrypt_block: rev RD, RD; #endif 2: + ldr RTAB, [%sp, #40]; sub %sp, #16; - GET_DATA_POINTER(RTAB, .LtableD0, RMASK); - mov RMASK, #0xff; str %r1, [%sp, #4]; /* dst */ mov RMASK, RMASK, lsl#3; /* byte mask */ @@ -591,279 +578,5 @@ _gcry_aes_arm_decrypt_block: b .Ldec_tail; .size _gcry_aes_arm_encrypt_block,.-_gcry_aes_arm_encrypt_block; -.data - -/* Encryption tables */ -.align 5 -.type .LtableE0, %object -.type .LtableEs0, %object -.LtableE0: -.long 0xa56363c6 -.LtableEs0: -.long 0x00000063, 0x847c7cf8, 0x0000007c -.long 0x997777ee, 0x00000077, 0x8d7b7bf6, 0x0000007b -.long 0x0df2f2ff, 0x000000f2, 0xbd6b6bd6, 0x0000006b -.long 0xb16f6fde, 0x0000006f, 0x54c5c591, 0x000000c5 -.long 0x50303060, 0x00000030, 0x03010102, 0x00000001 -.long 0xa96767ce, 0x00000067, 0x7d2b2b56, 0x0000002b -.long 0x19fefee7, 0x000000fe, 0x62d7d7b5, 0x000000d7 -.long 0xe6abab4d, 0x000000ab, 0x9a7676ec, 0x00000076 -.long 0x45caca8f, 0x000000ca, 0x9d82821f, 0x00000082 -.long 0x40c9c989, 0x000000c9, 0x877d7dfa, 0x0000007d -.long 0x15fafaef, 0x000000fa, 0xeb5959b2, 0x00000059 -.long 0xc947478e, 0x00000047, 0x0bf0f0fb, 0x000000f0 -.long 0xecadad41, 0x000000ad, 0x67d4d4b3, 0x000000d4 -.long 0xfda2a25f, 0x000000a2, 0xeaafaf45, 0x000000af -.long 0xbf9c9c23, 0x0000009c, 0xf7a4a453, 0x000000a4 -.long 0x967272e4, 0x00000072, 0x5bc0c09b, 0x000000c0 -.long 0xc2b7b775, 0x000000b7, 0x1cfdfde1, 0x000000fd -.long 0xae93933d, 0x00000093, 0x6a26264c, 0x00000026 -.long 0x5a36366c, 0x00000036, 0x413f3f7e, 0x0000003f -.long 0x02f7f7f5, 0x000000f7, 0x4fcccc83, 0x000000cc -.long 0x5c343468, 0x00000034, 0xf4a5a551, 0x000000a5 -.long 0x34e5e5d1, 0x000000e5, 0x08f1f1f9, 0x000000f1 -.long 0x937171e2, 0x00000071, 0x73d8d8ab, 0x000000d8 -.long 0x53313162, 0x00000031, 0x3f15152a, 0x00000015 -.long 0x0c040408, 0x00000004, 0x52c7c795, 0x000000c7 -.long 0x65232346, 0x00000023, 0x5ec3c39d, 0x000000c3 -.long 0x28181830, 0x00000018, 0xa1969637, 0x00000096 -.long 0x0f05050a, 0x00000005, 0xb59a9a2f, 0x0000009a -.long 0x0907070e, 0x00000007, 0x36121224, 0x00000012 -.long 0x9b80801b, 0x00000080, 0x3de2e2df, 0x000000e2 -.long 0x26ebebcd, 0x000000eb, 0x6927274e, 0x00000027 -.long 0xcdb2b27f, 0x000000b2, 0x9f7575ea, 0x00000075 -.long 0x1b090912, 0x00000009, 0x9e83831d, 0x00000083 -.long 0x742c2c58, 0x0000002c, 0x2e1a1a34, 0x0000001a -.long 0x2d1b1b36, 0x0000001b, 0xb26e6edc, 0x0000006e -.long 0xee5a5ab4, 0x0000005a, 0xfba0a05b, 0x000000a0 -.long 0xf65252a4, 0x00000052, 0x4d3b3b76, 0x0000003b -.long 0x61d6d6b7, 0x000000d6, 0xceb3b37d, 0x000000b3 -.long 0x7b292952, 0x00000029, 0x3ee3e3dd, 0x000000e3 -.long 0x712f2f5e, 0x0000002f, 0x97848413, 0x00000084 -.long 0xf55353a6, 0x00000053, 0x68d1d1b9, 0x000000d1 -.long 0x00000000, 0x00000000, 0x2cededc1, 0x000000ed -.long 0x60202040, 0x00000020, 0x1ffcfce3, 0x000000fc -.long 0xc8b1b179, 0x000000b1, 0xed5b5bb6, 0x0000005b -.long 0xbe6a6ad4, 0x0000006a, 0x46cbcb8d, 0x000000cb -.long 0xd9bebe67, 0x000000be, 0x4b393972, 0x00000039 -.long 0xde4a4a94, 0x0000004a, 0xd44c4c98, 0x0000004c -.long 0xe85858b0, 0x00000058, 0x4acfcf85, 0x000000cf -.long 0x6bd0d0bb, 0x000000d0, 0x2aefefc5, 0x000000ef -.long 0xe5aaaa4f, 0x000000aa, 0x16fbfbed, 0x000000fb -.long 0xc5434386, 0x00000043, 0xd74d4d9a, 0x0000004d -.long 0x55333366, 0x00000033, 0x94858511, 0x00000085 -.long 0xcf45458a, 0x00000045, 0x10f9f9e9, 0x000000f9 -.long 0x06020204, 0x00000002, 0x817f7ffe, 0x0000007f -.long 0xf05050a0, 0x00000050, 0x443c3c78, 0x0000003c -.long 0xba9f9f25, 0x0000009f, 0xe3a8a84b, 0x000000a8 -.long 0xf35151a2, 0x00000051, 0xfea3a35d, 0x000000a3 -.long 0xc0404080, 0x00000040, 0x8a8f8f05, 0x0000008f -.long 0xad92923f, 0x00000092, 0xbc9d9d21, 0x0000009d -.long 0x48383870, 0x00000038, 0x04f5f5f1, 0x000000f5 -.long 0xdfbcbc63, 0x000000bc, 0xc1b6b677, 0x000000b6 -.long 0x75dadaaf, 0x000000da, 0x63212142, 0x00000021 -.long 0x30101020, 0x00000010, 0x1affffe5, 0x000000ff -.long 0x0ef3f3fd, 0x000000f3, 0x6dd2d2bf, 0x000000d2 -.long 0x4ccdcd81, 0x000000cd, 0x140c0c18, 0x0000000c -.long 0x35131326, 0x00000013, 0x2fececc3, 0x000000ec -.long 0xe15f5fbe, 0x0000005f, 0xa2979735, 0x00000097 -.long 0xcc444488, 0x00000044, 0x3917172e, 0x00000017 -.long 0x57c4c493, 0x000000c4, 0xf2a7a755, 0x000000a7 -.long 0x827e7efc, 0x0000007e, 0x473d3d7a, 0x0000003d -.long 0xac6464c8, 0x00000064, 0xe75d5dba, 0x0000005d -.long 0x2b191932, 0x00000019, 0x957373e6, 0x00000073 -.long 0xa06060c0, 0x00000060, 0x98818119, 0x00000081 -.long 0xd14f4f9e, 0x0000004f, 0x7fdcdca3, 0x000000dc -.long 0x66222244, 0x00000022, 0x7e2a2a54, 0x0000002a -.long 0xab90903b, 0x00000090, 0x8388880b, 0x00000088 -.long 0xca46468c, 0x00000046, 0x29eeeec7, 0x000000ee -.long 0xd3b8b86b, 0x000000b8, 0x3c141428, 0x00000014 -.long 0x79dedea7, 0x000000de, 0xe25e5ebc, 0x0000005e -.long 0x1d0b0b16, 0x0000000b, 0x76dbdbad, 0x000000db -.long 0x3be0e0db, 0x000000e0, 0x56323264, 0x00000032 -.long 0x4e3a3a74, 0x0000003a, 0x1e0a0a14, 0x0000000a -.long 0xdb494992, 0x00000049, 0x0a06060c, 0x00000006 -.long 0x6c242448, 0x00000024, 0xe45c5cb8, 0x0000005c -.long 0x5dc2c29f, 0x000000c2, 0x6ed3d3bd, 0x000000d3 -.long 0xefacac43, 0x000000ac, 0xa66262c4, 0x00000062 -.long 0xa8919139, 0x00000091, 0xa4959531, 0x00000095 -.long 0x37e4e4d3, 0x000000e4, 0x8b7979f2, 0x00000079 -.long 0x32e7e7d5, 0x000000e7, 0x43c8c88b, 0x000000c8 -.long 0x5937376e, 0x00000037, 0xb76d6dda, 0x0000006d -.long 0x8c8d8d01, 0x0000008d, 0x64d5d5b1, 0x000000d5 -.long 0xd24e4e9c, 0x0000004e, 0xe0a9a949, 0x000000a9 -.long 0xb46c6cd8, 0x0000006c, 0xfa5656ac, 0x00000056 -.long 0x07f4f4f3, 0x000000f4, 0x25eaeacf, 0x000000ea -.long 0xaf6565ca, 0x00000065, 0x8e7a7af4, 0x0000007a -.long 0xe9aeae47, 0x000000ae, 0x18080810, 0x00000008 -.long 0xd5baba6f, 0x000000ba, 0x887878f0, 0x00000078 -.long 0x6f25254a, 0x00000025, 0x722e2e5c, 0x0000002e -.long 0x241c1c38, 0x0000001c, 0xf1a6a657, 0x000000a6 -.long 0xc7b4b473, 0x000000b4, 0x51c6c697, 0x000000c6 -.long 0x23e8e8cb, 0x000000e8, 0x7cdddda1, 0x000000dd -.long 0x9c7474e8, 0x00000074, 0x211f1f3e, 0x0000001f -.long 0xdd4b4b96, 0x0000004b, 0xdcbdbd61, 0x000000bd -.long 0x868b8b0d, 0x0000008b, 0x858a8a0f, 0x0000008a -.long 0x907070e0, 0x00000070, 0x423e3e7c, 0x0000003e -.long 0xc4b5b571, 0x000000b5, 0xaa6666cc, 0x00000066 -.long 0xd8484890, 0x00000048, 0x05030306, 0x00000003 -.long 0x01f6f6f7, 0x000000f6, 0x120e0e1c, 0x0000000e -.long 0xa36161c2, 0x00000061, 0x5f35356a, 0x00000035 -.long 0xf95757ae, 0x00000057, 0xd0b9b969, 0x000000b9 -.long 0x91868617, 0x00000086, 0x58c1c199, 0x000000c1 -.long 0x271d1d3a, 0x0000001d, 0xb99e9e27, 0x0000009e -.long 0x38e1e1d9, 0x000000e1, 0x13f8f8eb, 0x000000f8 -.long 0xb398982b, 0x00000098, 0x33111122, 0x00000011 -.long 0xbb6969d2, 0x00000069, 0x70d9d9a9, 0x000000d9 -.long 0x898e8e07, 0x0000008e, 0xa7949433, 0x00000094 -.long 0xb69b9b2d, 0x0000009b, 0x221e1e3c, 0x0000001e -.long 0x92878715, 0x00000087, 0x20e9e9c9, 0x000000e9 -.long 0x49cece87, 0x000000ce, 0xff5555aa, 0x00000055 -.long 0x78282850, 0x00000028, 0x7adfdfa5, 0x000000df -.long 0x8f8c8c03, 0x0000008c, 0xf8a1a159, 0x000000a1 -.long 0x80898909, 0x00000089, 0x170d0d1a, 0x0000000d -.long 0xdabfbf65, 0x000000bf, 0x31e6e6d7, 0x000000e6 -.long 0xc6424284, 0x00000042, 0xb86868d0, 0x00000068 -.long 0xc3414182, 0x00000041, 0xb0999929, 0x00000099 -.long 0x772d2d5a, 0x0000002d, 0x110f0f1e, 0x0000000f -.long 0xcbb0b07b, 0x000000b0, 0xfc5454a8, 0x00000054 -.long 0xd6bbbb6d, 0x000000bb, 0x3a16162c, 0x00000016 - -/* Decryption tables */ -.align 5 -.type .LtableD0, %object -.type .LtableDs0, %object -.LtableD0: -.long 0x50a7f451 -.LtableDs0: -.long 0x00000052, 0x5365417e, 0x00000009 -.long 0xc3a4171a, 0x0000006a, 0x965e273a, 0x000000d5 -.long 0xcb6bab3b, 0x00000030, 0xf1459d1f, 0x00000036 -.long 0xab58faac, 0x000000a5, 0x9303e34b, 0x00000038 -.long 0x55fa3020, 0x000000bf, 0xf66d76ad, 0x00000040 -.long 0x9176cc88, 0x000000a3, 0x254c02f5, 0x0000009e -.long 0xfcd7e54f, 0x00000081, 0xd7cb2ac5, 0x000000f3 -.long 0x80443526, 0x000000d7, 0x8fa362b5, 0x000000fb -.long 0x495ab1de, 0x0000007c, 0x671bba25, 0x000000e3 -.long 0x980eea45, 0x00000039, 0xe1c0fe5d, 0x00000082 -.long 0x02752fc3, 0x0000009b, 0x12f04c81, 0x0000002f -.long 0xa397468d, 0x000000ff, 0xc6f9d36b, 0x00000087 -.long 0xe75f8f03, 0x00000034, 0x959c9215, 0x0000008e -.long 0xeb7a6dbf, 0x00000043, 0xda595295, 0x00000044 -.long 0x2d83bed4, 0x000000c4, 0xd3217458, 0x000000de -.long 0x2969e049, 0x000000e9, 0x44c8c98e, 0x000000cb -.long 0x6a89c275, 0x00000054, 0x78798ef4, 0x0000007b -.long 0x6b3e5899, 0x00000094, 0xdd71b927, 0x00000032 -.long 0xb64fe1be, 0x000000a6, 0x17ad88f0, 0x000000c2 -.long 0x66ac20c9, 0x00000023, 0xb43ace7d, 0x0000003d -.long 0x184adf63, 0x000000ee, 0x82311ae5, 0x0000004c -.long 0x60335197, 0x00000095, 0x457f5362, 0x0000000b -.long 0xe07764b1, 0x00000042, 0x84ae6bbb, 0x000000fa -.long 0x1ca081fe, 0x000000c3, 0x942b08f9, 0x0000004e -.long 0x58684870, 0x00000008, 0x19fd458f, 0x0000002e -.long 0x876cde94, 0x000000a1, 0xb7f87b52, 0x00000066 -.long 0x23d373ab, 0x00000028, 0xe2024b72, 0x000000d9 -.long 0x578f1fe3, 0x00000024, 0x2aab5566, 0x000000b2 -.long 0x0728ebb2, 0x00000076, 0x03c2b52f, 0x0000005b -.long 0x9a7bc586, 0x000000a2, 0xa50837d3, 0x00000049 -.long 0xf2872830, 0x0000006d, 0xb2a5bf23, 0x0000008b -.long 0xba6a0302, 0x000000d1, 0x5c8216ed, 0x00000025 -.long 0x2b1ccf8a, 0x00000072, 0x92b479a7, 0x000000f8 -.long 0xf0f207f3, 0x000000f6, 0xa1e2694e, 0x00000064 -.long 0xcdf4da65, 0x00000086, 0xd5be0506, 0x00000068 -.long 0x1f6234d1, 0x00000098, 0x8afea6c4, 0x00000016 -.long 0x9d532e34, 0x000000d4, 0xa055f3a2, 0x000000a4 -.long 0x32e18a05, 0x0000005c, 0x75ebf6a4, 0x000000cc -.long 0x39ec830b, 0x0000005d, 0xaaef6040, 0x00000065 -.long 0x069f715e, 0x000000b6, 0x51106ebd, 0x00000092 -.long 0xf98a213e, 0x0000006c, 0x3d06dd96, 0x00000070 -.long 0xae053edd, 0x00000048, 0x46bde64d, 0x00000050 -.long 0xb58d5491, 0x000000fd, 0x055dc471, 0x000000ed -.long 0x6fd40604, 0x000000b9, 0xff155060, 0x000000da -.long 0x24fb9819, 0x0000005e, 0x97e9bdd6, 0x00000015 -.long 0xcc434089, 0x00000046, 0x779ed967, 0x00000057 -.long 0xbd42e8b0, 0x000000a7, 0x888b8907, 0x0000008d -.long 0x385b19e7, 0x0000009d, 0xdbeec879, 0x00000084 -.long 0x470a7ca1, 0x00000090, 0xe90f427c, 0x000000d8 -.long 0xc91e84f8, 0x000000ab, 0x00000000, 0x00000000 -.long 0x83868009, 0x0000008c, 0x48ed2b32, 0x000000bc -.long 0xac70111e, 0x000000d3, 0x4e725a6c, 0x0000000a -.long 0xfbff0efd, 0x000000f7, 0x5638850f, 0x000000e4 -.long 0x1ed5ae3d, 0x00000058, 0x27392d36, 0x00000005 -.long 0x64d90f0a, 0x000000b8, 0x21a65c68, 0x000000b3 -.long 0xd1545b9b, 0x00000045, 0x3a2e3624, 0x00000006 -.long 0xb1670a0c, 0x000000d0, 0x0fe75793, 0x0000002c -.long 0xd296eeb4, 0x0000001e, 0x9e919b1b, 0x0000008f -.long 0x4fc5c080, 0x000000ca, 0xa220dc61, 0x0000003f -.long 0x694b775a, 0x0000000f, 0x161a121c, 0x00000002 -.long 0x0aba93e2, 0x000000c1, 0xe52aa0c0, 0x000000af -.long 0x43e0223c, 0x000000bd, 0x1d171b12, 0x00000003 -.long 0x0b0d090e, 0x00000001, 0xadc78bf2, 0x00000013 -.long 0xb9a8b62d, 0x0000008a, 0xc8a91e14, 0x0000006b -.long 0x8519f157, 0x0000003a, 0x4c0775af, 0x00000091 -.long 0xbbdd99ee, 0x00000011, 0xfd607fa3, 0x00000041 -.long 0x9f2601f7, 0x0000004f, 0xbcf5725c, 0x00000067 -.long 0xc53b6644, 0x000000dc, 0x347efb5b, 0x000000ea -.long 0x7629438b, 0x00000097, 0xdcc623cb, 0x000000f2 -.long 0x68fcedb6, 0x000000cf, 0x63f1e4b8, 0x000000ce -.long 0xcadc31d7, 0x000000f0, 0x10856342, 0x000000b4 -.long 0x40229713, 0x000000e6, 0x2011c684, 0x00000073 -.long 0x7d244a85, 0x00000096, 0xf83dbbd2, 0x000000ac -.long 0x1132f9ae, 0x00000074, 0x6da129c7, 0x00000022 -.long 0x4b2f9e1d, 0x000000e7, 0xf330b2dc, 0x000000ad -.long 0xec52860d, 0x00000035, 0xd0e3c177, 0x00000085 -.long 0x6c16b32b, 0x000000e2, 0x99b970a9, 0x000000f9 -.long 0xfa489411, 0x00000037, 0x2264e947, 0x000000e8 -.long 0xc48cfca8, 0x0000001c, 0x1a3ff0a0, 0x00000075 -.long 0xd82c7d56, 0x000000df, 0xef903322, 0x0000006e -.long 0xc74e4987, 0x00000047, 0xc1d138d9, 0x000000f1 -.long 0xfea2ca8c, 0x0000001a, 0x360bd498, 0x00000071 -.long 0xcf81f5a6, 0x0000001d, 0x28de7aa5, 0x00000029 -.long 0x268eb7da, 0x000000c5, 0xa4bfad3f, 0x00000089 -.long 0xe49d3a2c, 0x0000006f, 0x0d927850, 0x000000b7 -.long 0x9bcc5f6a, 0x00000062, 0x62467e54, 0x0000000e -.long 0xc2138df6, 0x000000aa, 0xe8b8d890, 0x00000018 -.long 0x5ef7392e, 0x000000be, 0xf5afc382, 0x0000001b -.long 0xbe805d9f, 0x000000fc, 0x7c93d069, 0x00000056 -.long 0xa92dd56f, 0x0000003e, 0xb31225cf, 0x0000004b -.long 0x3b99acc8, 0x000000c6, 0xa77d1810, 0x000000d2 -.long 0x6e639ce8, 0x00000079, 0x7bbb3bdb, 0x00000020 -.long 0x097826cd, 0x0000009a, 0xf418596e, 0x000000db -.long 0x01b79aec, 0x000000c0, 0xa89a4f83, 0x000000fe -.long 0x656e95e6, 0x00000078, 0x7ee6ffaa, 0x000000cd -.long 0x08cfbc21, 0x0000005a, 0xe6e815ef, 0x000000f4 -.long 0xd99be7ba, 0x0000001f, 0xce366f4a, 0x000000dd -.long 0xd4099fea, 0x000000a8, 0xd67cb029, 0x00000033 -.long 0xafb2a431, 0x00000088, 0x31233f2a, 0x00000007 -.long 0x3094a5c6, 0x000000c7, 0xc066a235, 0x00000031 -.long 0x37bc4e74, 0x000000b1, 0xa6ca82fc, 0x00000012 -.long 0xb0d090e0, 0x00000010, 0x15d8a733, 0x00000059 -.long 0x4a9804f1, 0x00000027, 0xf7daec41, 0x00000080 -.long 0x0e50cd7f, 0x000000ec, 0x2ff69117, 0x0000005f -.long 0x8dd64d76, 0x00000060, 0x4db0ef43, 0x00000051 -.long 0x544daacc, 0x0000007f, 0xdf0496e4, 0x000000a9 -.long 0xe3b5d19e, 0x00000019, 0x1b886a4c, 0x000000b5 -.long 0xb81f2cc1, 0x0000004a, 0x7f516546, 0x0000000d -.long 0x04ea5e9d, 0x0000002d, 0x5d358c01, 0x000000e5 -.long 0x737487fa, 0x0000007a, 0x2e410bfb, 0x0000009f -.long 0x5a1d67b3, 0x00000093, 0x52d2db92, 0x000000c9 -.long 0x335610e9, 0x0000009c, 0x1347d66d, 0x000000ef -.long 0x8c61d79a, 0x000000a0, 0x7a0ca137, 0x000000e0 -.long 0x8e14f859, 0x0000003b, 0x893c13eb, 0x0000004d -.long 0xee27a9ce, 0x000000ae, 0x35c961b7, 0x0000002a -.long 0xede51ce1, 0x000000f5, 0x3cb1477a, 0x000000b0 -.long 0x59dfd29c, 0x000000c8, 0x3f73f255, 0x000000eb -.long 0x79ce1418, 0x000000bb, 0xbf37c773, 0x0000003c -.long 0xeacdf753, 0x00000083, 0x5baafd5f, 0x00000053 -.long 0x146f3ddf, 0x00000099, 0x86db4478, 0x00000061 -.long 0x81f3afca, 0x00000017, 0x3ec468b9, 0x0000002b -.long 0x2c342438, 0x00000004, 0x5f40a3c2, 0x0000007e -.long 0x72c31d16, 0x000000ba, 0x0c25e2bc, 0x00000077 -.long 0x8b493c28, 0x000000d6, 0x41950dff, 0x00000026 -.long 0x7101a839, 0x000000e1, 0xdeb30c08, 0x00000069 -.long 0x9ce4b4d8, 0x00000014, 0x90c15664, 0x00000063 -.long 0x6184cb7b, 0x00000055, 0x70b632d5, 0x00000021 -.long 0x745c6c48, 0x0000000c, 0x4257b8d0, 0x0000007d - #endif /*HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS*/ #endif /*__ARMEL__ */ diff --git a/cipher/rijndael-internal.h b/cipher/rijndael-internal.h index 9898f0c..7bc3790 100644 --- a/cipher/rijndael-internal.h +++ b/cipher/rijndael-internal.h @@ -79,6 +79,7 @@ struct RIJNDAEL_context_s; typedef unsigned int (*rijndael_cryptfn_t)(const struct RIJNDAEL_context_s *ctx, unsigned char *bx, const unsigned char *ax); +typedef void (*rijndael_prefetchfn_t)(void); /* Our context object. */ typedef struct RIJNDAEL_context_s @@ -115,6 +116,8 @@ typedef struct RIJNDAEL_context_s #endif /*USE_AESNI*/ rijndael_cryptfn_t encrypt_fn; rijndael_cryptfn_t decrypt_fn; + rijndael_prefetchfn_t prefetch_enc_fn; + rijndael_prefetchfn_t prefetch_dec_fn; } RIJNDAEL_context ATTR_ALIGNED_16; /* Macros defining alias for the keyschedules. */ diff --git a/cipher/rijndael-tables.h b/cipher/rijndael-tables.h index b6a5b15..5b58457 100644 --- a/cipher/rijndael-tables.h +++ b/cipher/rijndael-tables.h @@ -21,1661 +21,268 @@ /* To keep the actual implementation at a readable size we use this include file to define the tables. */ -static const unsigned char S[256] = +static const u32 encT[256][2] = { - 99, 124, 119, 123, 242, 107, 111, 197, - 48, 1, 103, 43, 254, 215, 171, 118, - 202, 130, 201, 125, 250, 89, 71, 240, - 173, 212, 162, 175, 156, 164, 114, 192, - 183, 253, 147, 38, 54, 63, 247, 204, - 52, 165, 229, 241, 113, 216, 49, 21, - 4, 199, 35, 195, 24, 150, 5, 154, - 7, 18, 128, 226, 235, 39, 178, 117, - 9, 131, 44, 26, 27, 110, 90, 160, - 82, 59, 214, 179, 41, 227, 47, 132, - 83, 209, 0, 237, 32, 252, 177, 91, - 106, 203, 190, 57, 74, 76, 88, 207, - 208, 239, 170, 251, 67, 77, 51, 133, - 69, 249, 2, 127, 80, 60, 159, 168, - 81, 163, 64, 143, 146, 157, 56, 245, - 188, 182, 218, 33, 16, 255, 243, 210, - 205, 12, 19, 236, 95, 151, 68, 23, - 196, 167, 126, 61, 100, 93, 25, 115, - 96, 129, 79, 220, 34, 42, 144, 136, - 70, 238, 184, 20, 222, 94, 11, 219, - 224, 50, 58, 10, 73, 6, 36, 92, - 194, 211, 172, 98, 145, 149, 228, 121, - 231, 200, 55, 109, 141, 213, 78, 169, - 108, 86, 244, 234, 101, 122, 174, 8, - 186, 120, 37, 46, 28, 166, 180, 198, - 232, 221, 116, 31, 75, 189, 139, 138, - 112, 62, 181, 102, 72, 3, 246, 14, - 97, 53, 87, 185, 134, 193, 29, 158, - 225, 248, 152, 17, 105, 217, 142, 148, - 155, 30, 135, 233, 206, 85, 40, 223, - 140, 161, 137, 13, 191, 230, 66, 104, - 65, 153, 45, 15, 176, 84, 187, 22 + { 0xa56363c6, 0x00000063 }, { 0x847c7cf8, 0x0000007c }, + { 0x997777ee, 0x00000077 }, { 0x8d7b7bf6, 0x0000007b }, + { 0x0df2f2ff, 0x000000f2 }, { 0xbd6b6bd6, 0x0000006b }, + { 0xb16f6fde, 0x0000006f }, { 0x54c5c591, 0x000000c5 }, + { 0x50303060, 0x00000030 }, { 0x03010102, 0x00000001 }, + { 0xa96767ce, 0x00000067 }, { 0x7d2b2b56, 0x0000002b }, + { 0x19fefee7, 0x000000fe }, { 0x62d7d7b5, 0x000000d7 }, + { 0xe6abab4d, 0x000000ab }, { 0x9a7676ec, 0x00000076 }, + { 0x45caca8f, 0x000000ca }, { 0x9d82821f, 0x00000082 }, + { 0x40c9c989, 0x000000c9 }, { 0x877d7dfa, 0x0000007d }, + { 0x15fafaef, 0x000000fa }, { 0xeb5959b2, 0x00000059 }, + { 0xc947478e, 0x00000047 }, { 0x0bf0f0fb, 0x000000f0 }, + { 0xecadad41, 0x000000ad }, { 0x67d4d4b3, 0x000000d4 }, + { 0xfda2a25f, 0x000000a2 }, { 0xeaafaf45, 0x000000af }, + { 0xbf9c9c23, 0x0000009c }, { 0xf7a4a453, 0x000000a4 }, + { 0x967272e4, 0x00000072 }, { 0x5bc0c09b, 0x000000c0 }, + { 0xc2b7b775, 0x000000b7 }, { 0x1cfdfde1, 0x000000fd }, + { 0xae93933d, 0x00000093 }, { 0x6a26264c, 0x00000026 }, + { 0x5a36366c, 0x00000036 }, { 0x413f3f7e, 0x0000003f }, + { 0x02f7f7f5, 0x000000f7 }, { 0x4fcccc83, 0x000000cc }, + { 0x5c343468, 0x00000034 }, { 0xf4a5a551, 0x000000a5 }, + { 0x34e5e5d1, 0x000000e5 }, { 0x08f1f1f9, 0x000000f1 }, + { 0x937171e2, 0x00000071 }, { 0x73d8d8ab, 0x000000d8 }, + { 0x53313162, 0x00000031 }, { 0x3f15152a, 0x00000015 }, + { 0x0c040408, 0x00000004 }, { 0x52c7c795, 0x000000c7 }, + { 0x65232346, 0x00000023 }, { 0x5ec3c39d, 0x000000c3 }, + { 0x28181830, 0x00000018 }, { 0xa1969637, 0x00000096 }, + { 0x0f05050a, 0x00000005 }, { 0xb59a9a2f, 0x0000009a }, + { 0x0907070e, 0x00000007 }, { 0x36121224, 0x00000012 }, + { 0x9b80801b, 0x00000080 }, { 0x3de2e2df, 0x000000e2 }, + { 0x26ebebcd, 0x000000eb }, { 0x6927274e, 0x00000027 }, + { 0xcdb2b27f, 0x000000b2 }, { 0x9f7575ea, 0x00000075 }, + { 0x1b090912, 0x00000009 }, { 0x9e83831d, 0x00000083 }, + { 0x742c2c58, 0x0000002c }, { 0x2e1a1a34, 0x0000001a }, + { 0x2d1b1b36, 0x0000001b }, { 0xb26e6edc, 0x0000006e }, + { 0xee5a5ab4, 0x0000005a }, { 0xfba0a05b, 0x000000a0 }, + { 0xf65252a4, 0x00000052 }, { 0x4d3b3b76, 0x0000003b }, + { 0x61d6d6b7, 0x000000d6 }, { 0xceb3b37d, 0x000000b3 }, + { 0x7b292952, 0x00000029 }, { 0x3ee3e3dd, 0x000000e3 }, + { 0x712f2f5e, 0x0000002f }, { 0x97848413, 0x00000084 }, + { 0xf55353a6, 0x00000053 }, { 0x68d1d1b9, 0x000000d1 }, + { 0x00000000, 0x00000000 }, { 0x2cededc1, 0x000000ed }, + { 0x60202040, 0x00000020 }, { 0x1ffcfce3, 0x000000fc }, + { 0xc8b1b179, 0x000000b1 }, { 0xed5b5bb6, 0x0000005b }, + { 0xbe6a6ad4, 0x0000006a }, { 0x46cbcb8d, 0x000000cb }, + { 0xd9bebe67, 0x000000be }, { 0x4b393972, 0x00000039 }, + { 0xde4a4a94, 0x0000004a }, { 0xd44c4c98, 0x0000004c }, + { 0xe85858b0, 0x00000058 }, { 0x4acfcf85, 0x000000cf }, + { 0x6bd0d0bb, 0x000000d0 }, { 0x2aefefc5, 0x000000ef }, + { 0xe5aaaa4f, 0x000000aa }, { 0x16fbfbed, 0x000000fb }, + { 0xc5434386, 0x00000043 }, { 0xd74d4d9a, 0x0000004d }, + { 0x55333366, 0x00000033 }, { 0x94858511, 0x00000085 }, + { 0xcf45458a, 0x00000045 }, { 0x10f9f9e9, 0x000000f9 }, + { 0x06020204, 0x00000002 }, { 0x817f7ffe, 0x0000007f }, + { 0xf05050a0, 0x00000050 }, { 0x443c3c78, 0x0000003c }, + { 0xba9f9f25, 0x0000009f }, { 0xe3a8a84b, 0x000000a8 }, + { 0xf35151a2, 0x00000051 }, { 0xfea3a35d, 0x000000a3 }, + { 0xc0404080, 0x00000040 }, { 0x8a8f8f05, 0x0000008f }, + { 0xad92923f, 0x00000092 }, { 0xbc9d9d21, 0x0000009d }, + { 0x48383870, 0x00000038 }, { 0x04f5f5f1, 0x000000f5 }, + { 0xdfbcbc63, 0x000000bc }, { 0xc1b6b677, 0x000000b6 }, + { 0x75dadaaf, 0x000000da }, { 0x63212142, 0x00000021 }, + { 0x30101020, 0x00000010 }, { 0x1affffe5, 0x000000ff }, + { 0x0ef3f3fd, 0x000000f3 }, { 0x6dd2d2bf, 0x000000d2 }, + { 0x4ccdcd81, 0x000000cd }, { 0x140c0c18, 0x0000000c }, + { 0x35131326, 0x00000013 }, { 0x2fececc3, 0x000000ec }, + { 0xe15f5fbe, 0x0000005f }, { 0xa2979735, 0x00000097 }, + { 0xcc444488, 0x00000044 }, { 0x3917172e, 0x00000017 }, + { 0x57c4c493, 0x000000c4 }, { 0xf2a7a755, 0x000000a7 }, + { 0x827e7efc, 0x0000007e }, { 0x473d3d7a, 0x0000003d }, + { 0xac6464c8, 0x00000064 }, { 0xe75d5dba, 0x0000005d }, + { 0x2b191932, 0x00000019 }, { 0x957373e6, 0x00000073 }, + { 0xa06060c0, 0x00000060 }, { 0x98818119, 0x00000081 }, + { 0xd14f4f9e, 0x0000004f }, { 0x7fdcdca3, 0x000000dc }, + { 0x66222244, 0x00000022 }, { 0x7e2a2a54, 0x0000002a }, + { 0xab90903b, 0x00000090 }, { 0x8388880b, 0x00000088 }, + { 0xca46468c, 0x00000046 }, { 0x29eeeec7, 0x000000ee }, + { 0xd3b8b86b, 0x000000b8 }, { 0x3c141428, 0x00000014 }, + { 0x79dedea7, 0x000000de }, { 0xe25e5ebc, 0x0000005e }, + { 0x1d0b0b16, 0x0000000b }, { 0x76dbdbad, 0x000000db }, + { 0x3be0e0db, 0x000000e0 }, { 0x56323264, 0x00000032 }, + { 0x4e3a3a74, 0x0000003a }, { 0x1e0a0a14, 0x0000000a }, + { 0xdb494992, 0x00000049 }, { 0x0a06060c, 0x00000006 }, + { 0x6c242448, 0x00000024 }, { 0xe45c5cb8, 0x0000005c }, + { 0x5dc2c29f, 0x000000c2 }, { 0x6ed3d3bd, 0x000000d3 }, + { 0xefacac43, 0x000000ac }, { 0xa66262c4, 0x00000062 }, + { 0xa8919139, 0x00000091 }, { 0xa4959531, 0x00000095 }, + { 0x37e4e4d3, 0x000000e4 }, { 0x8b7979f2, 0x00000079 }, + { 0x32e7e7d5, 0x000000e7 }, { 0x43c8c88b, 0x000000c8 }, + { 0x5937376e, 0x00000037 }, { 0xb76d6dda, 0x0000006d }, + { 0x8c8d8d01, 0x0000008d }, { 0x64d5d5b1, 0x000000d5 }, + { 0xd24e4e9c, 0x0000004e }, { 0xe0a9a949, 0x000000a9 }, + { 0xb46c6cd8, 0x0000006c }, { 0xfa5656ac, 0x00000056 }, + { 0x07f4f4f3, 0x000000f4 }, { 0x25eaeacf, 0x000000ea }, + { 0xaf6565ca, 0x00000065 }, { 0x8e7a7af4, 0x0000007a }, + { 0xe9aeae47, 0x000000ae }, { 0x18080810, 0x00000008 }, + { 0xd5baba6f, 0x000000ba }, { 0x887878f0, 0x00000078 }, + { 0x6f25254a, 0x00000025 }, { 0x722e2e5c, 0x0000002e }, + { 0x241c1c38, 0x0000001c }, { 0xf1a6a657, 0x000000a6 }, + { 0xc7b4b473, 0x000000b4 }, { 0x51c6c697, 0x000000c6 }, + { 0x23e8e8cb, 0x000000e8 }, { 0x7cdddda1, 0x000000dd }, + { 0x9c7474e8, 0x00000074 }, { 0x211f1f3e, 0x0000001f }, + { 0xdd4b4b96, 0x0000004b }, { 0xdcbdbd61, 0x000000bd }, + { 0x868b8b0d, 0x0000008b }, { 0x858a8a0f, 0x0000008a }, + { 0x907070e0, 0x00000070 }, { 0x423e3e7c, 0x0000003e }, + { 0xc4b5b571, 0x000000b5 }, { 0xaa6666cc, 0x00000066 }, + { 0xd8484890, 0x00000048 }, { 0x05030306, 0x00000003 }, + { 0x01f6f6f7, 0x000000f6 }, { 0x120e0e1c, 0x0000000e }, + { 0xa36161c2, 0x00000061 }, { 0x5f35356a, 0x00000035 }, + { 0xf95757ae, 0x00000057 }, { 0xd0b9b969, 0x000000b9 }, + { 0x91868617, 0x00000086 }, { 0x58c1c199, 0x000000c1 }, + { 0x271d1d3a, 0x0000001d }, { 0xb99e9e27, 0x0000009e }, + { 0x38e1e1d9, 0x000000e1 }, { 0x13f8f8eb, 0x000000f8 }, + { 0xb398982b, 0x00000098 }, { 0x33111122, 0x00000011 }, + { 0xbb6969d2, 0x00000069 }, { 0x70d9d9a9, 0x000000d9 }, + { 0x898e8e07, 0x0000008e }, { 0xa7949433, 0x00000094 }, + { 0xb69b9b2d, 0x0000009b }, { 0x221e1e3c, 0x0000001e }, + { 0x92878715, 0x00000087 }, { 0x20e9e9c9, 0x000000e9 }, + { 0x49cece87, 0x000000ce }, { 0xff5555aa, 0x00000055 }, + { 0x78282850, 0x00000028 }, { 0x7adfdfa5, 0x000000df }, + { 0x8f8c8c03, 0x0000008c }, { 0xf8a1a159, 0x000000a1 }, + { 0x80898909, 0x00000089 }, { 0x170d0d1a, 0x0000000d }, + { 0xdabfbf65, 0x000000bf }, { 0x31e6e6d7, 0x000000e6 }, + { 0xc6424284, 0x00000042 }, { 0xb86868d0, 0x00000068 }, + { 0xc3414182, 0x00000041 }, { 0xb0999929, 0x00000099 }, + { 0x772d2d5a, 0x0000002d }, { 0x110f0f1e, 0x0000000f }, + { 0xcbb0b07b, 0x000000b0 }, { 0xfc5454a8, 0x00000054 }, + { 0xd6bbbb6d, 0x000000bb }, { 0x3a16162c, 0x00000016 } }; - -static const unsigned char T1[256][4] = - { - { 0xc6,0x63,0x63,0xa5 }, { 0xf8,0x7c,0x7c,0x84 }, - { 0xee,0x77,0x77,0x99 }, { 0xf6,0x7b,0x7b,0x8d }, - { 0xff,0xf2,0xf2,0x0d }, { 0xd6,0x6b,0x6b,0xbd }, - { 0xde,0x6f,0x6f,0xb1 }, { 0x91,0xc5,0xc5,0x54 }, - { 0x60,0x30,0x30,0x50 }, { 0x02,0x01,0x01,0x03 }, - { 0xce,0x67,0x67,0xa9 }, { 0x56,0x2b,0x2b,0x7d }, - { 0xe7,0xfe,0xfe,0x19 }, { 0xb5,0xd7,0xd7,0x62 }, - { 0x4d,0xab,0xab,0xe6 }, { 0xec,0x76,0x76,0x9a }, - { 0x8f,0xca,0xca,0x45 }, { 0x1f,0x82,0x82,0x9d }, - { 0x89,0xc9,0xc9,0x40 }, { 0xfa,0x7d,0x7d,0x87 }, - { 0xef,0xfa,0xfa,0x15 }, { 0xb2,0x59,0x59,0xeb }, - { 0x8e,0x47,0x47,0xc9 }, { 0xfb,0xf0,0xf0,0x0b }, - { 0x41,0xad,0xad,0xec }, { 0xb3,0xd4,0xd4,0x67 }, - { 0x5f,0xa2,0xa2,0xfd }, { 0x45,0xaf,0xaf,0xea }, - { 0x23,0x9c,0x9c,0xbf }, { 0x53,0xa4,0xa4,0xf7 }, - { 0xe4,0x72,0x72,0x96 }, { 0x9b,0xc0,0xc0,0x5b }, - { 0x75,0xb7,0xb7,0xc2 }, { 0xe1,0xfd,0xfd,0x1c }, - { 0x3d,0x93,0x93,0xae }, { 0x4c,0x26,0x26,0x6a }, - { 0x6c,0x36,0x36,0x5a }, { 0x7e,0x3f,0x3f,0x41 }, - { 0xf5,0xf7,0xf7,0x02 }, { 0x83,0xcc,0xcc,0x4f }, - { 0x68,0x34,0x34,0x5c }, { 0x51,0xa5,0xa5,0xf4 }, - { 0xd1,0xe5,0xe5,0x34 }, { 0xf9,0xf1,0xf1,0x08 }, - { 0xe2,0x71,0x71,0x93 }, { 0xab,0xd8,0xd8,0x73 }, - { 0x62,0x31,0x31,0x53 }, { 0x2a,0x15,0x15,0x3f }, - { 0x08,0x04,0x04,0x0c }, { 0x95,0xc7,0xc7,0x52 }, - { 0x46,0x23,0x23,0x65 }, { 0x9d,0xc3,0xc3,0x5e }, - { 0x30,0x18,0x18,0x28 }, { 0x37,0x96,0x96,0xa1 }, - { 0x0a,0x05,0x05,0x0f }, { 0x2f,0x9a,0x9a,0xb5 }, - { 0x0e,0x07,0x07,0x09 }, { 0x24,0x12,0x12,0x36 }, - { 0x1b,0x80,0x80,0x9b }, { 0xdf,0xe2,0xe2,0x3d }, - { 0xcd,0xeb,0xeb,0x26 }, { 0x4e,0x27,0x27,0x69 }, - { 0x7f,0xb2,0xb2,0xcd }, { 0xea,0x75,0x75,0x9f }, - { 0x12,0x09,0x09,0x1b }, { 0x1d,0x83,0x83,0x9e }, - { 0x58,0x2c,0x2c,0x74 }, { 0x34,0x1a,0x1a,0x2e }, - { 0x36,0x1b,0x1b,0x2d }, { 0xdc,0x6e,0x6e,0xb2 }, - { 0xb4,0x5a,0x5a,0xee }, { 0x5b,0xa0,0xa0,0xfb }, - { 0xa4,0x52,0x52,0xf6 }, { 0x76,0x3b,0x3b,0x4d }, - { 0xb7,0xd6,0xd6,0x61 }, { 0x7d,0xb3,0xb3,0xce }, - { 0x52,0x29,0x29,0x7b }, { 0xdd,0xe3,0xe3,0x3e }, - { 0x5e,0x2f,0x2f,0x71 }, { 0x13,0x84,0x84,0x97 }, - { 0xa6,0x53,0x53,0xf5 }, { 0xb9,0xd1,0xd1,0x68 }, - { 0x00,0x00,0x00,0x00 }, { 0xc1,0xed,0xed,0x2c }, - { 0x40,0x20,0x20,0x60 }, { 0xe3,0xfc,0xfc,0x1f }, - { 0x79,0xb1,0xb1,0xc8 }, { 0xb6,0x5b,0x5b,0xed }, - { 0xd4,0x6a,0x6a,0xbe }, { 0x8d,0xcb,0xcb,0x46 }, - { 0x67,0xbe,0xbe,0xd9 }, { 0x72,0x39,0x39,0x4b }, - { 0x94,0x4a,0x4a,0xde }, { 0x98,0x4c,0x4c,0xd4 }, - { 0xb0,0x58,0x58,0xe8 }, { 0x85,0xcf,0xcf,0x4a }, - { 0xbb,0xd0,0xd0,0x6b }, { 0xc5,0xef,0xef,0x2a }, - { 0x4f,0xaa,0xaa,0xe5 }, { 0xed,0xfb,0xfb,0x16 }, - { 0x86,0x43,0x43,0xc5 }, { 0x9a,0x4d,0x4d,0xd7 }, - { 0x66,0x33,0x33,0x55 }, { 0x11,0x85,0x85,0x94 }, - { 0x8a,0x45,0x45,0xcf }, { 0xe9,0xf9,0xf9,0x10 }, - { 0x04,0x02,0x02,0x06 }, { 0xfe,0x7f,0x7f,0x81 }, - { 0xa0,0x50,0x50,0xf0 }, { 0x78,0x3c,0x3c,0x44 }, - { 0x25,0x9f,0x9f,0xba }, { 0x4b,0xa8,0xa8,0xe3 }, - { 0xa2,0x51,0x51,0xf3 }, { 0x5d,0xa3,0xa3,0xfe }, - { 0x80,0x40,0x40,0xc0 }, { 0x05,0x8f,0x8f,0x8a }, - { 0x3f,0x92,0x92,0xad }, { 0x21,0x9d,0x9d,0xbc }, - { 0x70,0x38,0x38,0x48 }, { 0xf1,0xf5,0xf5,0x04 }, - { 0x63,0xbc,0xbc,0xdf }, { 0x77,0xb6,0xb6,0xc1 }, - { 0xaf,0xda,0xda,0x75 }, { 0x42,0x21,0x21,0x63 }, - { 0x20,0x10,0x10,0x30 }, { 0xe5,0xff,0xff,0x1a }, - { 0xfd,0xf3,0xf3,0x0e }, { 0xbf,0xd2,0xd2,0x6d }, - { 0x81,0xcd,0xcd,0x4c }, { 0x18,0x0c,0x0c,0x14 }, - { 0x26,0x13,0x13,0x35 }, { 0xc3,0xec,0xec,0x2f }, - { 0xbe,0x5f,0x5f,0xe1 }, { 0x35,0x97,0x97,0xa2 }, - { 0x88,0x44,0x44,0xcc }, { 0x2e,0x17,0x17,0x39 }, - { 0x93,0xc4,0xc4,0x57 }, { 0x55,0xa7,0xa7,0xf2 }, - { 0xfc,0x7e,0x7e,0x82 }, { 0x7a,0x3d,0x3d,0x47 }, - { 0xc8,0x64,0x64,0xac }, { 0xba,0x5d,0x5d,0xe7 }, - { 0x32,0x19,0x19,0x2b }, { 0xe6,0x73,0x73,0x95 }, - { 0xc0,0x60,0x60,0xa0 }, { 0x19,0x81,0x81,0x98 }, - { 0x9e,0x4f,0x4f,0xd1 }, { 0xa3,0xdc,0xdc,0x7f }, - { 0x44,0x22,0x22,0x66 }, { 0x54,0x2a,0x2a,0x7e }, - { 0x3b,0x90,0x90,0xab }, { 0x0b,0x88,0x88,0x83 }, - { 0x8c,0x46,0x46,0xca }, { 0xc7,0xee,0xee,0x29 }, - { 0x6b,0xb8,0xb8,0xd3 }, { 0x28,0x14,0x14,0x3c }, - { 0xa7,0xde,0xde,0x79 }, { 0xbc,0x5e,0x5e,0xe2 }, - { 0x16,0x0b,0x0b,0x1d }, { 0xad,0xdb,0xdb,0x76 }, - { 0xdb,0xe0,0xe0,0x3b }, { 0x64,0x32,0x32,0x56 }, - { 0x74,0x3a,0x3a,0x4e }, { 0x14,0x0a,0x0a,0x1e }, - { 0x92,0x49,0x49,0xdb }, { 0x0c,0x06,0x06,0x0a }, - { 0x48,0x24,0x24,0x6c }, { 0xb8,0x5c,0x5c,0xe4 }, - { 0x9f,0xc2,0xc2,0x5d }, { 0xbd,0xd3,0xd3,0x6e }, - { 0x43,0xac,0xac,0xef }, { 0xc4,0x62,0x62,0xa6 }, - { 0x39,0x91,0x91,0xa8 }, { 0x31,0x95,0x95,0xa4 }, - { 0xd3,0xe4,0xe4,0x37 }, { 0xf2,0x79,0x79,0x8b }, - { 0xd5,0xe7,0xe7,0x32 }, { 0x8b,0xc8,0xc8,0x43 }, - { 0x6e,0x37,0x37,0x59 }, { 0xda,0x6d,0x6d,0xb7 }, - { 0x01,0x8d,0x8d,0x8c }, { 0xb1,0xd5,0xd5,0x64 }, - { 0x9c,0x4e,0x4e,0xd2 }, { 0x49,0xa9,0xa9,0xe0 }, - { 0xd8,0x6c,0x6c,0xb4 }, { 0xac,0x56,0x56,0xfa }, - { 0xf3,0xf4,0xf4,0x07 }, { 0xcf,0xea,0xea,0x25 }, - { 0xca,0x65,0x65,0xaf }, { 0xf4,0x7a,0x7a,0x8e }, - { 0x47,0xae,0xae,0xe9 }, { 0x10,0x08,0x08,0x18 }, - { 0x6f,0xba,0xba,0xd5 }, { 0xf0,0x78,0x78,0x88 }, - { 0x4a,0x25,0x25,0x6f }, { 0x5c,0x2e,0x2e,0x72 }, - { 0x38,0x1c,0x1c,0x24 }, { 0x57,0xa6,0xa6,0xf1 }, - { 0x73,0xb4,0xb4,0xc7 }, { 0x97,0xc6,0xc6,0x51 }, - { 0xcb,0xe8,0xe8,0x23 }, { 0xa1,0xdd,0xdd,0x7c }, - { 0xe8,0x74,0x74,0x9c }, { 0x3e,0x1f,0x1f,0x21 }, - { 0x96,0x4b,0x4b,0xdd }, { 0x61,0xbd,0xbd,0xdc }, - { 0x0d,0x8b,0x8b,0x86 }, { 0x0f,0x8a,0x8a,0x85 }, - { 0xe0,0x70,0x70,0x90 }, { 0x7c,0x3e,0x3e,0x42 }, - { 0x71,0xb5,0xb5,0xc4 }, { 0xcc,0x66,0x66,0xaa }, - { 0x90,0x48,0x48,0xd8 }, { 0x06,0x03,0x03,0x05 }, - { 0xf7,0xf6,0xf6,0x01 }, { 0x1c,0x0e,0x0e,0x12 }, - { 0xc2,0x61,0x61,0xa3 }, { 0x6a,0x35,0x35,0x5f }, - { 0xae,0x57,0x57,0xf9 }, { 0x69,0xb9,0xb9,0xd0 }, - { 0x17,0x86,0x86,0x91 }, { 0x99,0xc1,0xc1,0x58 }, - { 0x3a,0x1d,0x1d,0x27 }, { 0x27,0x9e,0x9e,0xb9 }, - { 0xd9,0xe1,0xe1,0x38 }, { 0xeb,0xf8,0xf8,0x13 }, - { 0x2b,0x98,0x98,0xb3 }, { 0x22,0x11,0x11,0x33 }, - { 0xd2,0x69,0x69,0xbb }, { 0xa9,0xd9,0xd9,0x70 }, - { 0x07,0x8e,0x8e,0x89 }, { 0x33,0x94,0x94,0xa7 }, - { 0x2d,0x9b,0x9b,0xb6 }, { 0x3c,0x1e,0x1e,0x22 }, - { 0x15,0x87,0x87,0x92 }, { 0xc9,0xe9,0xe9,0x20 }, - { 0x87,0xce,0xce,0x49 }, { 0xaa,0x55,0x55,0xff }, - { 0x50,0x28,0x28,0x78 }, { 0xa5,0xdf,0xdf,0x7a }, - { 0x03,0x8c,0x8c,0x8f }, { 0x59,0xa1,0xa1,0xf8 }, - { 0x09,0x89,0x89,0x80 }, { 0x1a,0x0d,0x0d,0x17 }, - { 0x65,0xbf,0xbf,0xda }, { 0xd7,0xe6,0xe6,0x31 }, - { 0x84,0x42,0x42,0xc6 }, { 0xd0,0x68,0x68,0xb8 }, - { 0x82,0x41,0x41,0xc3 }, { 0x29,0x99,0x99,0xb0 }, - { 0x5a,0x2d,0x2d,0x77 }, { 0x1e,0x0f,0x0f,0x11 }, - { 0x7b,0xb0,0xb0,0xcb }, { 0xa8,0x54,0x54,0xfc }, - { 0x6d,0xbb,0xbb,0xd6 }, { 0x2c,0x16,0x16,0x3a } - }; - -static const unsigned char T2[256][4] = - { - { 0xa5,0xc6,0x63,0x63 }, { 0x84,0xf8,0x7c,0x7c }, - { 0x99,0xee,0x77,0x77 }, { 0x8d,0xf6,0x7b,0x7b }, - { 0x0d,0xff,0xf2,0xf2 }, { 0xbd,0xd6,0x6b,0x6b }, - { 0xb1,0xde,0x6f,0x6f }, { 0x54,0x91,0xc5,0xc5 }, - { 0x50,0x60,0x30,0x30 }, { 0x03,0x02,0x01,0x01 }, - { 0xa9,0xce,0x67,0x67 }, { 0x7d,0x56,0x2b,0x2b }, - { 0x19,0xe7,0xfe,0xfe }, { 0x62,0xb5,0xd7,0xd7 }, - { 0xe6,0x4d,0xab,0xab }, { 0x9a,0xec,0x76,0x76 }, - { 0x45,0x8f,0xca,0xca }, { 0x9d,0x1f,0x82,0x82 }, - { 0x40,0x89,0xc9,0xc9 }, { 0x87,0xfa,0x7d,0x7d }, - { 0x15,0xef,0xfa,0xfa }, { 0xeb,0xb2,0x59,0x59 }, - { 0xc9,0x8e,0x47,0x47 }, { 0x0b,0xfb,0xf0,0xf0 }, - { 0xec,0x41,0xad,0xad }, { 0x67,0xb3,0xd4,0xd4 }, - { 0xfd,0x5f,0xa2,0xa2 }, { 0xea,0x45,0xaf,0xaf }, - { 0xbf,0x23,0x9c,0x9c }, { 0xf7,0x53,0xa4,0xa4 }, - { 0x96,0xe4,0x72,0x72 }, { 0x5b,0x9b,0xc0,0xc0 }, - { 0xc2,0x75,0xb7,0xb7 }, { 0x1c,0xe1,0xfd,0xfd }, - { 0xae,0x3d,0x93,0x93 }, { 0x6a,0x4c,0x26,0x26 }, - { 0x5a,0x6c,0x36,0x36 }, { 0x41,0x7e,0x3f,0x3f }, - { 0x02,0xf5,0xf7,0xf7 }, { 0x4f,0x83,0xcc,0xcc }, - { 0x5c,0x68,0x34,0x34 }, { 0xf4,0x51,0xa5,0xa5 }, - { 0x34,0xd1,0xe5,0xe5 }, { 0x08,0xf9,0xf1,0xf1 }, - { 0x93,0xe2,0x71,0x71 }, { 0x73,0xab,0xd8,0xd8 }, - { 0x53,0x62,0x31,0x31 }, { 0x3f,0x2a,0x15,0x15 }, - { 0x0c,0x08,0x04,0x04 }, { 0x52,0x95,0xc7,0xc7 }, - { 0x65,0x46,0x23,0x23 }, { 0x5e,0x9d,0xc3,0xc3 }, - { 0x28,0x30,0x18,0x18 }, { 0xa1,0x37,0x96,0x96 }, - { 0x0f,0x0a,0x05,0x05 }, { 0xb5,0x2f,0x9a,0x9a }, - { 0x09,0x0e,0x07,0x07 }, { 0x36,0x24,0x12,0x12 }, - { 0x9b,0x1b,0x80,0x80 }, { 0x3d,0xdf,0xe2,0xe2 }, - { 0x26,0xcd,0xeb,0xeb }, { 0x69,0x4e,0x27,0x27 }, - { 0xcd,0x7f,0xb2,0xb2 }, { 0x9f,0xea,0x75,0x75 }, - { 0x1b,0x12,0x09,0x09 }, { 0x9e,0x1d,0x83,0x83 }, - { 0x74,0x58,0x2c,0x2c }, { 0x2e,0x34,0x1a,0x1a }, - { 0x2d,0x36,0x1b,0x1b }, { 0xb2,0xdc,0x6e,0x6e }, - { 0xee,0xb4,0x5a,0x5a }, { 0xfb,0x5b,0xa0,0xa0 }, - { 0xf6,0xa4,0x52,0x52 }, { 0x4d,0x76,0x3b,0x3b }, - { 0x61,0xb7,0xd6,0xd6 }, { 0xce,0x7d,0xb3,0xb3 }, - { 0x7b,0x52,0x29,0x29 }, { 0x3e,0xdd,0xe3,0xe3 }, - { 0x71,0x5e,0x2f,0x2f }, { 0x97,0x13,0x84,0x84 }, - { 0xf5,0xa6,0x53,0x53 }, { 0x68,0xb9,0xd1,0xd1 }, - { 0x00,0x00,0x00,0x00 }, { 0x2c,0xc1,0xed,0xed }, - { 0x60,0x40,0x20,0x20 }, { 0x1f,0xe3,0xfc,0xfc }, - { 0xc8,0x79,0xb1,0xb1 }, { 0xed,0xb6,0x5b,0x5b }, - { 0xbe,0xd4,0x6a,0x6a }, { 0x46,0x8d,0xcb,0xcb }, - { 0xd9,0x67,0xbe,0xbe }, { 0x4b,0x72,0x39,0x39 }, - { 0xde,0x94,0x4a,0x4a }, { 0xd4,0x98,0x4c,0x4c }, - { 0xe8,0xb0,0x58,0x58 }, { 0x4a,0x85,0xcf,0xcf }, - { 0x6b,0xbb,0xd0,0xd0 }, { 0x2a,0xc5,0xef,0xef }, - { 0xe5,0x4f,0xaa,0xaa }, { 0x16,0xed,0xfb,0xfb }, - { 0xc5,0x86,0x43,0x43 }, { 0xd7,0x9a,0x4d,0x4d }, - { 0x55,0x66,0x33,0x33 }, { 0x94,0x11,0x85,0x85 }, - { 0xcf,0x8a,0x45,0x45 }, { 0x10,0xe9,0xf9,0xf9 }, - { 0x06,0x04,0x02,0x02 }, { 0x81,0xfe,0x7f,0x7f }, - { 0xf0,0xa0,0x50,0x50 }, { 0x44,0x78,0x3c,0x3c }, - { 0xba,0x25,0x9f,0x9f }, { 0xe3,0x4b,0xa8,0xa8 }, - { 0xf3,0xa2,0x51,0x51 }, { 0xfe,0x5d,0xa3,0xa3 }, - { 0xc0,0x80,0x40,0x40 }, { 0x8a,0x05,0x8f,0x8f }, - { 0xad,0x3f,0x92,0x92 }, { 0xbc,0x21,0x9d,0x9d }, - { 0x48,0x70,0x38,0x38 }, { 0x04,0xf1,0xf5,0xf5 }, - { 0xdf,0x63,0xbc,0xbc }, { 0xc1,0x77,0xb6,0xb6 }, - { 0x75,0xaf,0xda,0xda }, { 0x63,0x42,0x21,0x21 }, - { 0x30,0x20,0x10,0x10 }, { 0x1a,0xe5,0xff,0xff }, - { 0x0e,0xfd,0xf3,0xf3 }, { 0x6d,0xbf,0xd2,0xd2 }, - { 0x4c,0x81,0xcd,0xcd }, { 0x14,0x18,0x0c,0x0c }, - { 0x35,0x26,0x13,0x13 }, { 0x2f,0xc3,0xec,0xec }, - { 0xe1,0xbe,0x5f,0x5f }, { 0xa2,0x35,0x97,0x97 }, - { 0xcc,0x88,0x44,0x44 }, { 0x39,0x2e,0x17,0x17 }, - { 0x57,0x93,0xc4,0xc4 }, { 0xf2,0x55,0xa7,0xa7 }, - { 0x82,0xfc,0x7e,0x7e }, { 0x47,0x7a,0x3d,0x3d }, - { 0xac,0xc8,0x64,0x64 }, { 0xe7,0xba,0x5d,0x5d }, - { 0x2b,0x32,0x19,0x19 }, { 0x95,0xe6,0x73,0x73 }, - { 0xa0,0xc0,0x60,0x60 }, { 0x98,0x19,0x81,0x81 }, - { 0xd1,0x9e,0x4f,0x4f }, { 0x7f,0xa3,0xdc,0xdc }, - { 0x66,0x44,0x22,0x22 }, { 0x7e,0x54,0x2a,0x2a }, - { 0xab,0x3b,0x90,0x90 }, { 0x83,0x0b,0x88,0x88 }, - { 0xca,0x8c,0x46,0x46 }, { 0x29,0xc7,0xee,0xee }, - { 0xd3,0x6b,0xb8,0xb8 }, { 0x3c,0x28,0x14,0x14 }, - { 0x79,0xa7,0xde,0xde }, { 0xe2,0xbc,0x5e,0x5e }, - { 0x1d,0x16,0x0b,0x0b }, { 0x76,0xad,0xdb,0xdb }, - { 0x3b,0xdb,0xe0,0xe0 }, { 0x56,0x64,0x32,0x32 }, - { 0x4e,0x74,0x3a,0x3a }, { 0x1e,0x14,0x0a,0x0a }, - { 0xdb,0x92,0x49,0x49 }, { 0x0a,0x0c,0x06,0x06 }, - { 0x6c,0x48,0x24,0x24 }, { 0xe4,0xb8,0x5c,0x5c }, - { 0x5d,0x9f,0xc2,0xc2 }, { 0x6e,0xbd,0xd3,0xd3 }, - { 0xef,0x43,0xac,0xac }, { 0xa6,0xc4,0x62,0x62 }, - { 0xa8,0x39,0x91,0x91 }, { 0xa4,0x31,0x95,0x95 }, - { 0x37,0xd3,0xe4,0xe4 }, { 0x8b,0xf2,0x79,0x79 }, - { 0x32,0xd5,0xe7,0xe7 }, { 0x43,0x8b,0xc8,0xc8 }, - { 0x59,0x6e,0x37,0x37 }, { 0xb7,0xda,0x6d,0x6d }, - { 0x8c,0x01,0x8d,0x8d }, { 0x64,0xb1,0xd5,0xd5 }, - { 0xd2,0x9c,0x4e,0x4e }, { 0xe0,0x49,0xa9,0xa9 }, - { 0xb4,0xd8,0x6c,0x6c }, { 0xfa,0xac,0x56,0x56 }, - { 0x07,0xf3,0xf4,0xf4 }, { 0x25,0xcf,0xea,0xea }, - { 0xaf,0xca,0x65,0x65 }, { 0x8e,0xf4,0x7a,0x7a }, - { 0xe9,0x47,0xae,0xae }, { 0x18,0x10,0x08,0x08 }, - { 0xd5,0x6f,0xba,0xba }, { 0x88,0xf0,0x78,0x78 }, - { 0x6f,0x4a,0x25,0x25 }, { 0x72,0x5c,0x2e,0x2e }, - { 0x24,0x38,0x1c,0x1c }, { 0xf1,0x57,0xa6,0xa6 }, - { 0xc7,0x73,0xb4,0xb4 }, { 0x51,0x97,0xc6,0xc6 }, - { 0x23,0xcb,0xe8,0xe8 }, { 0x7c,0xa1,0xdd,0xdd }, - { 0x9c,0xe8,0x74,0x74 }, { 0x21,0x3e,0x1f,0x1f }, - { 0xdd,0x96,0x4b,0x4b }, { 0xdc,0x61,0xbd,0xbd }, - { 0x86,0x0d,0x8b,0x8b }, { 0x85,0x0f,0x8a,0x8a }, - { 0x90,0xe0,0x70,0x70 }, { 0x42,0x7c,0x3e,0x3e }, - { 0xc4,0x71,0xb5,0xb5 }, { 0xaa,0xcc,0x66,0x66 }, - { 0xd8,0x90,0x48,0x48 }, { 0x05,0x06,0x03,0x03 }, - { 0x01,0xf7,0xf6,0xf6 }, { 0x12,0x1c,0x0e,0x0e }, - { 0xa3,0xc2,0x61,0x61 }, { 0x5f,0x6a,0x35,0x35 }, - { 0xf9,0xae,0x57,0x57 }, { 0xd0,0x69,0xb9,0xb9 }, - { 0x91,0x17,0x86,0x86 }, { 0x58,0x99,0xc1,0xc1 }, - { 0x27,0x3a,0x1d,0x1d }, { 0xb9,0x27,0x9e,0x9e }, - { 0x38,0xd9,0xe1,0xe1 }, { 0x13,0xeb,0xf8,0xf8 }, - { 0xb3,0x2b,0x98,0x98 }, { 0x33,0x22,0x11,0x11 }, - { 0xbb,0xd2,0x69,0x69 }, { 0x70,0xa9,0xd9,0xd9 }, - { 0x89,0x07,0x8e,0x8e }, { 0xa7,0x33,0x94,0x94 }, - { 0xb6,0x2d,0x9b,0x9b }, { 0x22,0x3c,0x1e,0x1e }, - { 0x92,0x15,0x87,0x87 }, { 0x20,0xc9,0xe9,0xe9 }, - { 0x49,0x87,0xce,0xce }, { 0xff,0xaa,0x55,0x55 }, - { 0x78,0x50,0x28,0x28 }, { 0x7a,0xa5,0xdf,0xdf }, - { 0x8f,0x03,0x8c,0x8c }, { 0xf8,0x59,0xa1,0xa1 }, - { 0x80,0x09,0x89,0x89 }, { 0x17,0x1a,0x0d,0x0d }, - { 0xda,0x65,0xbf,0xbf }, { 0x31,0xd7,0xe6,0xe6 }, - { 0xc6,0x84,0x42,0x42 }, { 0xb8,0xd0,0x68,0x68 }, - { 0xc3,0x82,0x41,0x41 }, { 0xb0,0x29,0x99,0x99 }, - { 0x77,0x5a,0x2d,0x2d }, { 0x11,0x1e,0x0f,0x0f }, - { 0xcb,0x7b,0xb0,0xb0 }, { 0xfc,0xa8,0x54,0x54 }, - { 0xd6,0x6d,0xbb,0xbb }, { 0x3a,0x2c,0x16,0x16 } - }; - -static const unsigned char T3[256][4] = - { - { 0x63,0xa5,0xc6,0x63 }, { 0x7c,0x84,0xf8,0x7c }, - { 0x77,0x99,0xee,0x77 }, { 0x7b,0x8d,0xf6,0x7b }, - { 0xf2,0x0d,0xff,0xf2 }, { 0x6b,0xbd,0xd6,0x6b }, - { 0x6f,0xb1,0xde,0x6f }, { 0xc5,0x54,0x91,0xc5 }, - { 0x30,0x50,0x60,0x30 }, { 0x01,0x03,0x02,0x01 }, - { 0x67,0xa9,0xce,0x67 }, { 0x2b,0x7d,0x56,0x2b }, - { 0xfe,0x19,0xe7,0xfe }, { 0xd7,0x62,0xb5,0xd7 }, - { 0xab,0xe6,0x4d,0xab }, { 0x76,0x9a,0xec,0x76 }, - { 0xca,0x45,0x8f,0xca }, { 0x82,0x9d,0x1f,0x82 }, - { 0xc9,0x40,0x89,0xc9 }, { 0x7d,0x87,0xfa,0x7d }, - { 0xfa,0x15,0xef,0xfa }, { 0x59,0xeb,0xb2,0x59 }, - { 0x47,0xc9,0x8e,0x47 }, { 0xf0,0x0b,0xfb,0xf0 }, - { 0xad,0xec,0x41,0xad }, { 0xd4,0x67,0xb3,0xd4 }, - { 0xa2,0xfd,0x5f,0xa2 }, { 0xaf,0xea,0x45,0xaf }, - { 0x9c,0xbf,0x23,0x9c }, { 0xa4,0xf7,0x53,0xa4 }, - { 0x72,0x96,0xe4,0x72 }, { 0xc0,0x5b,0x9b,0xc0 }, - { 0xb7,0xc2,0x75,0xb7 }, { 0xfd,0x1c,0xe1,0xfd }, - { 0x93,0xae,0x3d,0x93 }, { 0x26,0x6a,0x4c,0x26 }, - { 0x36,0x5a,0x6c,0x36 }, { 0x3f,0x41,0x7e,0x3f }, - { 0xf7,0x02,0xf5,0xf7 }, { 0xcc,0x4f,0x83,0xcc }, - { 0x34,0x5c,0x68,0x34 }, { 0xa5,0xf4,0x51,0xa5 }, - { 0xe5,0x34,0xd1,0xe5 }, { 0xf1,0x08,0xf9,0xf1 }, - { 0x71,0x93,0xe2,0x71 }, { 0xd8,0x73,0xab,0xd8 }, - { 0x31,0x53,0x62,0x31 }, { 0x15,0x3f,0x2a,0x15 }, - { 0x04,0x0c,0x08,0x04 }, { 0xc7,0x52,0x95,0xc7 }, - { 0x23,0x65,0x46,0x23 }, { 0xc3,0x5e,0x9d,0xc3 }, - { 0x18,0x28,0x30,0x18 }, { 0x96,0xa1,0x37,0x96 }, - { 0x05,0x0f,0x0a,0x05 }, { 0x9a,0xb5,0x2f,0x9a }, - { 0x07,0x09,0x0e,0x07 }, { 0x12,0x36,0x24,0x12 }, - { 0x80,0x9b,0x1b,0x80 }, { 0xe2,0x3d,0xdf,0xe2 }, - { 0xeb,0x26,0xcd,0xeb }, { 0x27,0x69,0x4e,0x27 }, - { 0xb2,0xcd,0x7f,0xb2 }, { 0x75,0x9f,0xea,0x75 }, - { 0x09,0x1b,0x12,0x09 }, { 0x83,0x9e,0x1d,0x83 }, - { 0x2c,0x74,0x58,0x2c }, { 0x1a,0x2e,0x34,0x1a }, - { 0x1b,0x2d,0x36,0x1b }, { 0x6e,0xb2,0xdc,0x6e }, - { 0x5a,0xee,0xb4,0x5a }, { 0xa0,0xfb,0x5b,0xa0 }, - { 0x52,0xf6,0xa4,0x52 }, { 0x3b,0x4d,0x76,0x3b }, - { 0xd6,0x61,0xb7,0xd6 }, { 0xb3,0xce,0x7d,0xb3 }, - { 0x29,0x7b,0x52,0x29 }, { 0xe3,0x3e,0xdd,0xe3 }, - { 0x2f,0x71,0x5e,0x2f }, { 0x84,0x97,0x13,0x84 }, - { 0x53,0xf5,0xa6,0x53 }, { 0xd1,0x68,0xb9,0xd1 }, - { 0x00,0x00,0x00,0x00 }, { 0xed,0x2c,0xc1,0xed }, - { 0x20,0x60,0x40,0x20 }, { 0xfc,0x1f,0xe3,0xfc }, - { 0xb1,0xc8,0x79,0xb1 }, { 0x5b,0xed,0xb6,0x5b }, - { 0x6a,0xbe,0xd4,0x6a }, { 0xcb,0x46,0x8d,0xcb }, - { 0xbe,0xd9,0x67,0xbe }, { 0x39,0x4b,0x72,0x39 }, - { 0x4a,0xde,0x94,0x4a }, { 0x4c,0xd4,0x98,0x4c }, - { 0x58,0xe8,0xb0,0x58 }, { 0xcf,0x4a,0x85,0xcf }, - { 0xd0,0x6b,0xbb,0xd0 }, { 0xef,0x2a,0xc5,0xef }, - { 0xaa,0xe5,0x4f,0xaa }, { 0xfb,0x16,0xed,0xfb }, - { 0x43,0xc5,0x86,0x43 }, { 0x4d,0xd7,0x9a,0x4d }, - { 0x33,0x55,0x66,0x33 }, { 0x85,0x94,0x11,0x85 }, - { 0x45,0xcf,0x8a,0x45 }, { 0xf9,0x10,0xe9,0xf9 }, - { 0x02,0x06,0x04,0x02 }, { 0x7f,0x81,0xfe,0x7f }, - { 0x50,0xf0,0xa0,0x50 }, { 0x3c,0x44,0x78,0x3c }, - { 0x9f,0xba,0x25,0x9f }, { 0xa8,0xe3,0x4b,0xa8 }, - { 0x51,0xf3,0xa2,0x51 }, { 0xa3,0xfe,0x5d,0xa3 }, - { 0x40,0xc0,0x80,0x40 }, { 0x8f,0x8a,0x05,0x8f }, - { 0x92,0xad,0x3f,0x92 }, { 0x9d,0xbc,0x21,0x9d }, - { 0x38,0x48,0x70,0x38 }, { 0xf5,0x04,0xf1,0xf5 }, - { 0xbc,0xdf,0x63,0xbc }, { 0xb6,0xc1,0x77,0xb6 }, - { 0xda,0x75,0xaf,0xda }, { 0x21,0x63,0x42,0x21 }, - { 0x10,0x30,0x20,0x10 }, { 0xff,0x1a,0xe5,0xff }, - { 0xf3,0x0e,0xfd,0xf3 }, { 0xd2,0x6d,0xbf,0xd2 }, - { 0xcd,0x4c,0x81,0xcd }, { 0x0c,0x14,0x18,0x0c }, - { 0x13,0x35,0x26,0x13 }, { 0xec,0x2f,0xc3,0xec }, - { 0x5f,0xe1,0xbe,0x5f }, { 0x97,0xa2,0x35,0x97 }, - { 0x44,0xcc,0x88,0x44 }, { 0x17,0x39,0x2e,0x17 }, - { 0xc4,0x57,0x93,0xc4 }, { 0xa7,0xf2,0x55,0xa7 }, - { 0x7e,0x82,0xfc,0x7e }, { 0x3d,0x47,0x7a,0x3d }, - { 0x64,0xac,0xc8,0x64 }, { 0x5d,0xe7,0xba,0x5d }, - { 0x19,0x2b,0x32,0x19 }, { 0x73,0x95,0xe6,0x73 }, - { 0x60,0xa0,0xc0,0x60 }, { 0x81,0x98,0x19,0x81 }, - { 0x4f,0xd1,0x9e,0x4f }, { 0xdc,0x7f,0xa3,0xdc }, - { 0x22,0x66,0x44,0x22 }, { 0x2a,0x7e,0x54,0x2a }, - { 0x90,0xab,0x3b,0x90 }, { 0x88,0x83,0x0b,0x88 }, - { 0x46,0xca,0x8c,0x46 }, { 0xee,0x29,0xc7,0xee }, - { 0xb8,0xd3,0x6b,0xb8 }, { 0x14,0x3c,0x28,0x14 }, - { 0xde,0x79,0xa7,0xde }, { 0x5e,0xe2,0xbc,0x5e }, - { 0x0b,0x1d,0x16,0x0b }, { 0xdb,0x76,0xad,0xdb }, - { 0xe0,0x3b,0xdb,0xe0 }, { 0x32,0x56,0x64,0x32 }, - { 0x3a,0x4e,0x74,0x3a }, { 0x0a,0x1e,0x14,0x0a }, - { 0x49,0xdb,0x92,0x49 }, { 0x06,0x0a,0x0c,0x06 }, - { 0x24,0x6c,0x48,0x24 }, { 0x5c,0xe4,0xb8,0x5c }, - { 0xc2,0x5d,0x9f,0xc2 }, { 0xd3,0x6e,0xbd,0xd3 }, - { 0xac,0xef,0x43,0xac }, { 0x62,0xa6,0xc4,0x62 }, - { 0x91,0xa8,0x39,0x91 }, { 0x95,0xa4,0x31,0x95 }, - { 0xe4,0x37,0xd3,0xe4 }, { 0x79,0x8b,0xf2,0x79 }, - { 0xe7,0x32,0xd5,0xe7 }, { 0xc8,0x43,0x8b,0xc8 }, - { 0x37,0x59,0x6e,0x37 }, { 0x6d,0xb7,0xda,0x6d }, - { 0x8d,0x8c,0x01,0x8d }, { 0xd5,0x64,0xb1,0xd5 }, - { 0x4e,0xd2,0x9c,0x4e }, { 0xa9,0xe0,0x49,0xa9 }, - { 0x6c,0xb4,0xd8,0x6c }, { 0x56,0xfa,0xac,0x56 }, - { 0xf4,0x07,0xf3,0xf4 }, { 0xea,0x25,0xcf,0xea }, - { 0x65,0xaf,0xca,0x65 }, { 0x7a,0x8e,0xf4,0x7a }, - { 0xae,0xe9,0x47,0xae }, { 0x08,0x18,0x10,0x08 }, - { 0xba,0xd5,0x6f,0xba }, { 0x78,0x88,0xf0,0x78 }, - { 0x25,0x6f,0x4a,0x25 }, { 0x2e,0x72,0x5c,0x2e }, - { 0x1c,0x24,0x38,0x1c }, { 0xa6,0xf1,0x57,0xa6 }, - { 0xb4,0xc7,0x73,0xb4 }, { 0xc6,0x51,0x97,0xc6 }, - { 0xe8,0x23,0xcb,0xe8 }, { 0xdd,0x7c,0xa1,0xdd }, - { 0x74,0x9c,0xe8,0x74 }, { 0x1f,0x21,0x3e,0x1f }, - { 0x4b,0xdd,0x96,0x4b }, { 0xbd,0xdc,0x61,0xbd }, - { 0x8b,0x86,0x0d,0x8b }, { 0x8a,0x85,0x0f,0x8a }, - { 0x70,0x90,0xe0,0x70 }, { 0x3e,0x42,0x7c,0x3e }, - { 0xb5,0xc4,0x71,0xb5 }, { 0x66,0xaa,0xcc,0x66 }, - { 0x48,0xd8,0x90,0x48 }, { 0x03,0x05,0x06,0x03 }, - { 0xf6,0x01,0xf7,0xf6 }, { 0x0e,0x12,0x1c,0x0e }, - { 0x61,0xa3,0xc2,0x61 }, { 0x35,0x5f,0x6a,0x35 }, - { 0x57,0xf9,0xae,0x57 }, { 0xb9,0xd0,0x69,0xb9 }, - { 0x86,0x91,0x17,0x86 }, { 0xc1,0x58,0x99,0xc1 }, - { 0x1d,0x27,0x3a,0x1d }, { 0x9e,0xb9,0x27,0x9e }, - { 0xe1,0x38,0xd9,0xe1 }, { 0xf8,0x13,0xeb,0xf8 }, - { 0x98,0xb3,0x2b,0x98 }, { 0x11,0x33,0x22,0x11 }, - { 0x69,0xbb,0xd2,0x69 }, { 0xd9,0x70,0xa9,0xd9 }, - { 0x8e,0x89,0x07,0x8e }, { 0x94,0xa7,0x33,0x94 }, - { 0x9b,0xb6,0x2d,0x9b }, { 0x1e,0x22,0x3c,0x1e }, - { 0x87,0x92,0x15,0x87 }, { 0xe9,0x20,0xc9,0xe9 }, - { 0xce,0x49,0x87,0xce }, { 0x55,0xff,0xaa,0x55 }, - { 0x28,0x78,0x50,0x28 }, { 0xdf,0x7a,0xa5,0xdf }, - { 0x8c,0x8f,0x03,0x8c }, { 0xa1,0xf8,0x59,0xa1 }, - { 0x89,0x80,0x09,0x89 }, { 0x0d,0x17,0x1a,0x0d }, - { 0xbf,0xda,0x65,0xbf }, { 0xe6,0x31,0xd7,0xe6 }, - { 0x42,0xc6,0x84,0x42 }, { 0x68,0xb8,0xd0,0x68 }, - { 0x41,0xc3,0x82,0x41 }, { 0x99,0xb0,0x29,0x99 }, - { 0x2d,0x77,0x5a,0x2d }, { 0x0f,0x11,0x1e,0x0f }, - { 0xb0,0xcb,0x7b,0xb0 }, { 0x54,0xfc,0xa8,0x54 }, - { 0xbb,0xd6,0x6d,0xbb }, { 0x16,0x3a,0x2c,0x16 } - }; - -static const unsigned char T4[256][4] = - { - { 0x63,0x63,0xa5,0xc6 }, { 0x7c,0x7c,0x84,0xf8 }, - { 0x77,0x77,0x99,0xee }, { 0x7b,0x7b,0x8d,0xf6 }, - { 0xf2,0xf2,0x0d,0xff }, { 0x6b,0x6b,0xbd,0xd6 }, - { 0x6f,0x6f,0xb1,0xde }, { 0xc5,0xc5,0x54,0x91 }, - { 0x30,0x30,0x50,0x60 }, { 0x01,0x01,0x03,0x02 }, - { 0x67,0x67,0xa9,0xce }, { 0x2b,0x2b,0x7d,0x56 }, - { 0xfe,0xfe,0x19,0xe7 }, { 0xd7,0xd7,0x62,0xb5 }, - { 0xab,0xab,0xe6,0x4d }, { 0x76,0x76,0x9a,0xec }, - { 0xca,0xca,0x45,0x8f }, { 0x82,0x82,0x9d,0x1f }, - { 0xc9,0xc9,0x40,0x89 }, { 0x7d,0x7d,0x87,0xfa }, - { 0xfa,0xfa,0x15,0xef }, { 0x59,0x59,0xeb,0xb2 }, - { 0x47,0x47,0xc9,0x8e }, { 0xf0,0xf0,0x0b,0xfb }, - { 0xad,0xad,0xec,0x41 }, { 0xd4,0xd4,0x67,0xb3 }, - { 0xa2,0xa2,0xfd,0x5f }, { 0xaf,0xaf,0xea,0x45 }, - { 0x9c,0x9c,0xbf,0x23 }, { 0xa4,0xa4,0xf7,0x53 }, - { 0x72,0x72,0x96,0xe4 }, { 0xc0,0xc0,0x5b,0x9b }, - { 0xb7,0xb7,0xc2,0x75 }, { 0xfd,0xfd,0x1c,0xe1 }, - { 0x93,0x93,0xae,0x3d }, { 0x26,0x26,0x6a,0x4c }, - { 0x36,0x36,0x5a,0x6c }, { 0x3f,0x3f,0x41,0x7e }, - { 0xf7,0xf7,0x02,0xf5 }, { 0xcc,0xcc,0x4f,0x83 }, - { 0x34,0x34,0x5c,0x68 }, { 0xa5,0xa5,0xf4,0x51 }, - { 0xe5,0xe5,0x34,0xd1 }, { 0xf1,0xf1,0x08,0xf9 }, - { 0x71,0x71,0x93,0xe2 }, { 0xd8,0xd8,0x73,0xab }, - { 0x31,0x31,0x53,0x62 }, { 0x15,0x15,0x3f,0x2a }, - { 0x04,0x04,0x0c,0x08 }, { 0xc7,0xc7,0x52,0x95 }, - { 0x23,0x23,0x65,0x46 }, { 0xc3,0xc3,0x5e,0x9d }, - { 0x18,0x18,0x28,0x30 }, { 0x96,0x96,0xa1,0x37 }, - { 0x05,0x05,0x0f,0x0a }, { 0x9a,0x9a,0xb5,0x2f }, - { 0x07,0x07,0x09,0x0e }, { 0x12,0x12,0x36,0x24 }, - { 0x80,0x80,0x9b,0x1b }, { 0xe2,0xe2,0x3d,0xdf }, - { 0xeb,0xeb,0x26,0xcd }, { 0x27,0x27,0x69,0x4e }, - { 0xb2,0xb2,0xcd,0x7f }, { 0x75,0x75,0x9f,0xea }, - { 0x09,0x09,0x1b,0x12 }, { 0x83,0x83,0x9e,0x1d }, - { 0x2c,0x2c,0x74,0x58 }, { 0x1a,0x1a,0x2e,0x34 }, - { 0x1b,0x1b,0x2d,0x36 }, { 0x6e,0x6e,0xb2,0xdc }, - { 0x5a,0x5a,0xee,0xb4 }, { 0xa0,0xa0,0xfb,0x5b }, - { 0x52,0x52,0xf6,0xa4 }, { 0x3b,0x3b,0x4d,0x76 }, - { 0xd6,0xd6,0x61,0xb7 }, { 0xb3,0xb3,0xce,0x7d }, - { 0x29,0x29,0x7b,0x52 }, { 0xe3,0xe3,0x3e,0xdd }, - { 0x2f,0x2f,0x71,0x5e }, { 0x84,0x84,0x97,0x13 }, - { 0x53,0x53,0xf5,0xa6 }, { 0xd1,0xd1,0x68,0xb9 }, - { 0x00,0x00,0x00,0x00 }, { 0xed,0xed,0x2c,0xc1 }, - { 0x20,0x20,0x60,0x40 }, { 0xfc,0xfc,0x1f,0xe3 }, - { 0xb1,0xb1,0xc8,0x79 }, { 0x5b,0x5b,0xed,0xb6 }, - { 0x6a,0x6a,0xbe,0xd4 }, { 0xcb,0xcb,0x46,0x8d }, - { 0xbe,0xbe,0xd9,0x67 }, { 0x39,0x39,0x4b,0x72 }, - { 0x4a,0x4a,0xde,0x94 }, { 0x4c,0x4c,0xd4,0x98 }, - { 0x58,0x58,0xe8,0xb0 }, { 0xcf,0xcf,0x4a,0x85 }, - { 0xd0,0xd0,0x6b,0xbb }, { 0xef,0xef,0x2a,0xc5 }, - { 0xaa,0xaa,0xe5,0x4f }, { 0xfb,0xfb,0x16,0xed }, - { 0x43,0x43,0xc5,0x86 }, { 0x4d,0x4d,0xd7,0x9a }, - { 0x33,0x33,0x55,0x66 }, { 0x85,0x85,0x94,0x11 }, - { 0x45,0x45,0xcf,0x8a }, { 0xf9,0xf9,0x10,0xe9 }, - { 0x02,0x02,0x06,0x04 }, { 0x7f,0x7f,0x81,0xfe }, - { 0x50,0x50,0xf0,0xa0 }, { 0x3c,0x3c,0x44,0x78 }, - { 0x9f,0x9f,0xba,0x25 }, { 0xa8,0xa8,0xe3,0x4b }, - { 0x51,0x51,0xf3,0xa2 }, { 0xa3,0xa3,0xfe,0x5d }, - { 0x40,0x40,0xc0,0x80 }, { 0x8f,0x8f,0x8a,0x05 }, - { 0x92,0x92,0xad,0x3f }, { 0x9d,0x9d,0xbc,0x21 }, - { 0x38,0x38,0x48,0x70 }, { 0xf5,0xf5,0x04,0xf1 }, - { 0xbc,0xbc,0xdf,0x63 }, { 0xb6,0xb6,0xc1,0x77 }, - { 0xda,0xda,0x75,0xaf }, { 0x21,0x21,0x63,0x42 }, - { 0x10,0x10,0x30,0x20 }, { 0xff,0xff,0x1a,0xe5 }, - { 0xf3,0xf3,0x0e,0xfd }, { 0xd2,0xd2,0x6d,0xbf }, - { 0xcd,0xcd,0x4c,0x81 }, { 0x0c,0x0c,0x14,0x18 }, - { 0x13,0x13,0x35,0x26 }, { 0xec,0xec,0x2f,0xc3 }, - { 0x5f,0x5f,0xe1,0xbe }, { 0x97,0x97,0xa2,0x35 }, - { 0x44,0x44,0xcc,0x88 }, { 0x17,0x17,0x39,0x2e }, - { 0xc4,0xc4,0x57,0x93 }, { 0xa7,0xa7,0xf2,0x55 }, - { 0x7e,0x7e,0x82,0xfc }, { 0x3d,0x3d,0x47,0x7a }, - { 0x64,0x64,0xac,0xc8 }, { 0x5d,0x5d,0xe7,0xba }, - { 0x19,0x19,0x2b,0x32 }, { 0x73,0x73,0x95,0xe6 }, - { 0x60,0x60,0xa0,0xc0 }, { 0x81,0x81,0x98,0x19 }, - { 0x4f,0x4f,0xd1,0x9e }, { 0xdc,0xdc,0x7f,0xa3 }, - { 0x22,0x22,0x66,0x44 }, { 0x2a,0x2a,0x7e,0x54 }, - { 0x90,0x90,0xab,0x3b }, { 0x88,0x88,0x83,0x0b }, - { 0x46,0x46,0xca,0x8c }, { 0xee,0xee,0x29,0xc7 }, - { 0xb8,0xb8,0xd3,0x6b }, { 0x14,0x14,0x3c,0x28 }, - { 0xde,0xde,0x79,0xa7 }, { 0x5e,0x5e,0xe2,0xbc }, - { 0x0b,0x0b,0x1d,0x16 }, { 0xdb,0xdb,0x76,0xad }, - { 0xe0,0xe0,0x3b,0xdb }, { 0x32,0x32,0x56,0x64 }, - { 0x3a,0x3a,0x4e,0x74 }, { 0x0a,0x0a,0x1e,0x14 }, - { 0x49,0x49,0xdb,0x92 }, { 0x06,0x06,0x0a,0x0c }, - { 0x24,0x24,0x6c,0x48 }, { 0x5c,0x5c,0xe4,0xb8 }, - { 0xc2,0xc2,0x5d,0x9f }, { 0xd3,0xd3,0x6e,0xbd }, - { 0xac,0xac,0xef,0x43 }, { 0x62,0x62,0xa6,0xc4 }, - { 0x91,0x91,0xa8,0x39 }, { 0x95,0x95,0xa4,0x31 }, - { 0xe4,0xe4,0x37,0xd3 }, { 0x79,0x79,0x8b,0xf2 }, - { 0xe7,0xe7,0x32,0xd5 }, { 0xc8,0xc8,0x43,0x8b }, - { 0x37,0x37,0x59,0x6e }, { 0x6d,0x6d,0xb7,0xda }, - { 0x8d,0x8d,0x8c,0x01 }, { 0xd5,0xd5,0x64,0xb1 }, - { 0x4e,0x4e,0xd2,0x9c }, { 0xa9,0xa9,0xe0,0x49 }, - { 0x6c,0x6c,0xb4,0xd8 }, { 0x56,0x56,0xfa,0xac }, - { 0xf4,0xf4,0x07,0xf3 }, { 0xea,0xea,0x25,0xcf }, - { 0x65,0x65,0xaf,0xca }, { 0x7a,0x7a,0x8e,0xf4 }, - { 0xae,0xae,0xe9,0x47 }, { 0x08,0x08,0x18,0x10 }, - { 0xba,0xba,0xd5,0x6f }, { 0x78,0x78,0x88,0xf0 }, - { 0x25,0x25,0x6f,0x4a }, { 0x2e,0x2e,0x72,0x5c }, - { 0x1c,0x1c,0x24,0x38 }, { 0xa6,0xa6,0xf1,0x57 }, - { 0xb4,0xb4,0xc7,0x73 }, { 0xc6,0xc6,0x51,0x97 }, - { 0xe8,0xe8,0x23,0xcb }, { 0xdd,0xdd,0x7c,0xa1 }, - { 0x74,0x74,0x9c,0xe8 }, { 0x1f,0x1f,0x21,0x3e }, - { 0x4b,0x4b,0xdd,0x96 }, { 0xbd,0xbd,0xdc,0x61 }, - { 0x8b,0x8b,0x86,0x0d }, { 0x8a,0x8a,0x85,0x0f }, - { 0x70,0x70,0x90,0xe0 }, { 0x3e,0x3e,0x42,0x7c }, - { 0xb5,0xb5,0xc4,0x71 }, { 0x66,0x66,0xaa,0xcc }, - { 0x48,0x48,0xd8,0x90 }, { 0x03,0x03,0x05,0x06 }, - { 0xf6,0xf6,0x01,0xf7 }, { 0x0e,0x0e,0x12,0x1c }, - { 0x61,0x61,0xa3,0xc2 }, { 0x35,0x35,0x5f,0x6a }, - { 0x57,0x57,0xf9,0xae }, { 0xb9,0xb9,0xd0,0x69 }, - { 0x86,0x86,0x91,0x17 }, { 0xc1,0xc1,0x58,0x99 }, - { 0x1d,0x1d,0x27,0x3a }, { 0x9e,0x9e,0xb9,0x27 }, - { 0xe1,0xe1,0x38,0xd9 }, { 0xf8,0xf8,0x13,0xeb }, - { 0x98,0x98,0xb3,0x2b }, { 0x11,0x11,0x33,0x22 }, - { 0x69,0x69,0xbb,0xd2 }, { 0xd9,0xd9,0x70,0xa9 }, - { 0x8e,0x8e,0x89,0x07 }, { 0x94,0x94,0xa7,0x33 }, - { 0x9b,0x9b,0xb6,0x2d }, { 0x1e,0x1e,0x22,0x3c }, - { 0x87,0x87,0x92,0x15 }, { 0xe9,0xe9,0x20,0xc9 }, - { 0xce,0xce,0x49,0x87 }, { 0x55,0x55,0xff,0xaa }, - { 0x28,0x28,0x78,0x50 }, { 0xdf,0xdf,0x7a,0xa5 }, - { 0x8c,0x8c,0x8f,0x03 }, { 0xa1,0xa1,0xf8,0x59 }, - { 0x89,0x89,0x80,0x09 }, { 0x0d,0x0d,0x17,0x1a }, - { 0xbf,0xbf,0xda,0x65 }, { 0xe6,0xe6,0x31,0xd7 }, - { 0x42,0x42,0xc6,0x84 }, { 0x68,0x68,0xb8,0xd0 }, - { 0x41,0x41,0xc3,0x82 }, { 0x99,0x99,0xb0,0x29 }, - { 0x2d,0x2d,0x77,0x5a }, { 0x0f,0x0f,0x11,0x1e }, - { 0xb0,0xb0,0xcb,0x7b }, { 0x54,0x54,0xfc,0xa8 }, - { 0xbb,0xbb,0xd6,0x6d }, { 0x16,0x16,0x3a,0x2c } - }; - -static const unsigned char T5[256][4] = - { - { 0x51,0xf4,0xa7,0x50 }, { 0x7e,0x41,0x65,0x53 }, - { 0x1a,0x17,0xa4,0xc3 }, { 0x3a,0x27,0x5e,0x96 }, - { 0x3b,0xab,0x6b,0xcb }, { 0x1f,0x9d,0x45,0xf1 }, - { 0xac,0xfa,0x58,0xab }, { 0x4b,0xe3,0x03,0x93 }, - { 0x20,0x30,0xfa,0x55 }, { 0xad,0x76,0x6d,0xf6 }, - { 0x88,0xcc,0x76,0x91 }, { 0xf5,0x02,0x4c,0x25 }, - { 0x4f,0xe5,0xd7,0xfc }, { 0xc5,0x2a,0xcb,0xd7 }, - { 0x26,0x35,0x44,0x80 }, { 0xb5,0x62,0xa3,0x8f }, - { 0xde,0xb1,0x5a,0x49 }, { 0x25,0xba,0x1b,0x67 }, - { 0x45,0xea,0x0e,0x98 }, { 0x5d,0xfe,0xc0,0xe1 }, - { 0xc3,0x2f,0x75,0x02 }, { 0x81,0x4c,0xf0,0x12 }, - { 0x8d,0x46,0x97,0xa3 }, { 0x6b,0xd3,0xf9,0xc6 }, - { 0x03,0x8f,0x5f,0xe7 }, { 0x15,0x92,0x9c,0x95 }, - { 0xbf,0x6d,0x7a,0xeb }, { 0x95,0x52,0x59,0xda }, - { 0xd4,0xbe,0x83,0x2d }, { 0x58,0x74,0x21,0xd3 }, - { 0x49,0xe0,0x69,0x29 }, { 0x8e,0xc9,0xc8,0x44 }, - { 0x75,0xc2,0x89,0x6a }, { 0xf4,0x8e,0x79,0x78 }, - { 0x99,0x58,0x3e,0x6b }, { 0x27,0xb9,0x71,0xdd }, - { 0xbe,0xe1,0x4f,0xb6 }, { 0xf0,0x88,0xad,0x17 }, - { 0xc9,0x20,0xac,0x66 }, { 0x7d,0xce,0x3a,0xb4 }, - { 0x63,0xdf,0x4a,0x18 }, { 0xe5,0x1a,0x31,0x82 }, - { 0x97,0x51,0x33,0x60 }, { 0x62,0x53,0x7f,0x45 }, - { 0xb1,0x64,0x77,0xe0 }, { 0xbb,0x6b,0xae,0x84 }, - { 0xfe,0x81,0xa0,0x1c }, { 0xf9,0x08,0x2b,0x94 }, - { 0x70,0x48,0x68,0x58 }, { 0x8f,0x45,0xfd,0x19 }, - { 0x94,0xde,0x6c,0x87 }, { 0x52,0x7b,0xf8,0xb7 }, - { 0xab,0x73,0xd3,0x23 }, { 0x72,0x4b,0x02,0xe2 }, - { 0xe3,0x1f,0x8f,0x57 }, { 0x66,0x55,0xab,0x2a }, - { 0xb2,0xeb,0x28,0x07 }, { 0x2f,0xb5,0xc2,0x03 }, - { 0x86,0xc5,0x7b,0x9a }, { 0xd3,0x37,0x08,0xa5 }, - { 0x30,0x28,0x87,0xf2 }, { 0x23,0xbf,0xa5,0xb2 }, - { 0x02,0x03,0x6a,0xba }, { 0xed,0x16,0x82,0x5c }, - { 0x8a,0xcf,0x1c,0x2b }, { 0xa7,0x79,0xb4,0x92 }, - { 0xf3,0x07,0xf2,0xf0 }, { 0x4e,0x69,0xe2,0xa1 }, - { 0x65,0xda,0xf4,0xcd }, { 0x06,0x05,0xbe,0xd5 }, - { 0xd1,0x34,0x62,0x1f }, { 0xc4,0xa6,0xfe,0x8a }, - { 0x34,0x2e,0x53,0x9d }, { 0xa2,0xf3,0x55,0xa0 }, - { 0x05,0x8a,0xe1,0x32 }, { 0xa4,0xf6,0xeb,0x75 }, - { 0x0b,0x83,0xec,0x39 }, { 0x40,0x60,0xef,0xaa }, - { 0x5e,0x71,0x9f,0x06 }, { 0xbd,0x6e,0x10,0x51 }, - { 0x3e,0x21,0x8a,0xf9 }, { 0x96,0xdd,0x06,0x3d }, - { 0xdd,0x3e,0x05,0xae }, { 0x4d,0xe6,0xbd,0x46 }, - { 0x91,0x54,0x8d,0xb5 }, { 0x71,0xc4,0x5d,0x05 }, - { 0x04,0x06,0xd4,0x6f }, { 0x60,0x50,0x15,0xff }, - { 0x19,0x98,0xfb,0x24 }, { 0xd6,0xbd,0xe9,0x97 }, - { 0x89,0x40,0x43,0xcc }, { 0x67,0xd9,0x9e,0x77 }, - { 0xb0,0xe8,0x42,0xbd }, { 0x07,0x89,0x8b,0x88 }, - { 0xe7,0x19,0x5b,0x38 }, { 0x79,0xc8,0xee,0xdb }, - { 0xa1,0x7c,0x0a,0x47 }, { 0x7c,0x42,0x0f,0xe9 }, - { 0xf8,0x84,0x1e,0xc9 }, { 0x00,0x00,0x00,0x00 }, - { 0x09,0x80,0x86,0x83 }, { 0x32,0x2b,0xed,0x48 }, - { 0x1e,0x11,0x70,0xac }, { 0x6c,0x5a,0x72,0x4e }, - { 0xfd,0x0e,0xff,0xfb }, { 0x0f,0x85,0x38,0x56 }, - { 0x3d,0xae,0xd5,0x1e }, { 0x36,0x2d,0x39,0x27 }, - { 0x0a,0x0f,0xd9,0x64 }, { 0x68,0x5c,0xa6,0x21 }, - { 0x9b,0x5b,0x54,0xd1 }, { 0x24,0x36,0x2e,0x3a }, - { 0x0c,0x0a,0x67,0xb1 }, { 0x93,0x57,0xe7,0x0f }, - { 0xb4,0xee,0x96,0xd2 }, { 0x1b,0x9b,0x91,0x9e }, - { 0x80,0xc0,0xc5,0x4f }, { 0x61,0xdc,0x20,0xa2 }, - { 0x5a,0x77,0x4b,0x69 }, { 0x1c,0x12,0x1a,0x16 }, - { 0xe2,0x93,0xba,0x0a }, { 0xc0,0xa0,0x2a,0xe5 }, - { 0x3c,0x22,0xe0,0x43 }, { 0x12,0x1b,0x17,0x1d }, - { 0x0e,0x09,0x0d,0x0b }, { 0xf2,0x8b,0xc7,0xad }, - { 0x2d,0xb6,0xa8,0xb9 }, { 0x14,0x1e,0xa9,0xc8 }, - { 0x57,0xf1,0x19,0x85 }, { 0xaf,0x75,0x07,0x4c }, - { 0xee,0x99,0xdd,0xbb }, { 0xa3,0x7f,0x60,0xfd }, - { 0xf7,0x01,0x26,0x9f }, { 0x5c,0x72,0xf5,0xbc }, - { 0x44,0x66,0x3b,0xc5 }, { 0x5b,0xfb,0x7e,0x34 }, - { 0x8b,0x43,0x29,0x76 }, { 0xcb,0x23,0xc6,0xdc }, - { 0xb6,0xed,0xfc,0x68 }, { 0xb8,0xe4,0xf1,0x63 }, - { 0xd7,0x31,0xdc,0xca }, { 0x42,0x63,0x85,0x10 }, - { 0x13,0x97,0x22,0x40 }, { 0x84,0xc6,0x11,0x20 }, - { 0x85,0x4a,0x24,0x7d }, { 0xd2,0xbb,0x3d,0xf8 }, - { 0xae,0xf9,0x32,0x11 }, { 0xc7,0x29,0xa1,0x6d }, - { 0x1d,0x9e,0x2f,0x4b }, { 0xdc,0xb2,0x30,0xf3 }, - { 0x0d,0x86,0x52,0xec }, { 0x77,0xc1,0xe3,0xd0 }, - { 0x2b,0xb3,0x16,0x6c }, { 0xa9,0x70,0xb9,0x99 }, - { 0x11,0x94,0x48,0xfa }, { 0x47,0xe9,0x64,0x22 }, - { 0xa8,0xfc,0x8c,0xc4 }, { 0xa0,0xf0,0x3f,0x1a }, - { 0x56,0x7d,0x2c,0xd8 }, { 0x22,0x33,0x90,0xef }, - { 0x87,0x49,0x4e,0xc7 }, { 0xd9,0x38,0xd1,0xc1 }, - { 0x8c,0xca,0xa2,0xfe }, { 0x98,0xd4,0x0b,0x36 }, - { 0xa6,0xf5,0x81,0xcf }, { 0xa5,0x7a,0xde,0x28 }, - { 0xda,0xb7,0x8e,0x26 }, { 0x3f,0xad,0xbf,0xa4 }, - { 0x2c,0x3a,0x9d,0xe4 }, { 0x50,0x78,0x92,0x0d }, - { 0x6a,0x5f,0xcc,0x9b }, { 0x54,0x7e,0x46,0x62 }, - { 0xf6,0x8d,0x13,0xc2 }, { 0x90,0xd8,0xb8,0xe8 }, - { 0x2e,0x39,0xf7,0x5e }, { 0x82,0xc3,0xaf,0xf5 }, - { 0x9f,0x5d,0x80,0xbe }, { 0x69,0xd0,0x93,0x7c }, - { 0x6f,0xd5,0x2d,0xa9 }, { 0xcf,0x25,0x12,0xb3 }, - { 0xc8,0xac,0x99,0x3b }, { 0x10,0x18,0x7d,0xa7 }, - { 0xe8,0x9c,0x63,0x6e }, { 0xdb,0x3b,0xbb,0x7b }, - { 0xcd,0x26,0x78,0x09 }, { 0x6e,0x59,0x18,0xf4 }, - { 0xec,0x9a,0xb7,0x01 }, { 0x83,0x4f,0x9a,0xa8 }, - { 0xe6,0x95,0x6e,0x65 }, { 0xaa,0xff,0xe6,0x7e }, - { 0x21,0xbc,0xcf,0x08 }, { 0xef,0x15,0xe8,0xe6 }, - { 0xba,0xe7,0x9b,0xd9 }, { 0x4a,0x6f,0x36,0xce }, - { 0xea,0x9f,0x09,0xd4 }, { 0x29,0xb0,0x7c,0xd6 }, - { 0x31,0xa4,0xb2,0xaf }, { 0x2a,0x3f,0x23,0x31 }, - { 0xc6,0xa5,0x94,0x30 }, { 0x35,0xa2,0x66,0xc0 }, - { 0x74,0x4e,0xbc,0x37 }, { 0xfc,0x82,0xca,0xa6 }, - { 0xe0,0x90,0xd0,0xb0 }, { 0x33,0xa7,0xd8,0x15 }, - { 0xf1,0x04,0x98,0x4a }, { 0x41,0xec,0xda,0xf7 }, - { 0x7f,0xcd,0x50,0x0e }, { 0x17,0x91,0xf6,0x2f }, - { 0x76,0x4d,0xd6,0x8d }, { 0x43,0xef,0xb0,0x4d }, - { 0xcc,0xaa,0x4d,0x54 }, { 0xe4,0x96,0x04,0xdf }, - { 0x9e,0xd1,0xb5,0xe3 }, { 0x4c,0x6a,0x88,0x1b }, - { 0xc1,0x2c,0x1f,0xb8 }, { 0x46,0x65,0x51,0x7f }, - { 0x9d,0x5e,0xea,0x04 }, { 0x01,0x8c,0x35,0x5d }, - { 0xfa,0x87,0x74,0x73 }, { 0xfb,0x0b,0x41,0x2e }, - { 0xb3,0x67,0x1d,0x5a }, { 0x92,0xdb,0xd2,0x52 }, - { 0xe9,0x10,0x56,0x33 }, { 0x6d,0xd6,0x47,0x13 }, - { 0x9a,0xd7,0x61,0x8c }, { 0x37,0xa1,0x0c,0x7a }, - { 0x59,0xf8,0x14,0x8e }, { 0xeb,0x13,0x3c,0x89 }, - { 0xce,0xa9,0x27,0xee }, { 0xb7,0x61,0xc9,0x35 }, - { 0xe1,0x1c,0xe5,0xed }, { 0x7a,0x47,0xb1,0x3c }, - { 0x9c,0xd2,0xdf,0x59 }, { 0x55,0xf2,0x73,0x3f }, - { 0x18,0x14,0xce,0x79 }, { 0x73,0xc7,0x37,0xbf }, - { 0x53,0xf7,0xcd,0xea }, { 0x5f,0xfd,0xaa,0x5b }, - { 0xdf,0x3d,0x6f,0x14 }, { 0x78,0x44,0xdb,0x86 }, - { 0xca,0xaf,0xf3,0x81 }, { 0xb9,0x68,0xc4,0x3e }, - { 0x38,0x24,0x34,0x2c }, { 0xc2,0xa3,0x40,0x5f }, - { 0x16,0x1d,0xc3,0x72 }, { 0xbc,0xe2,0x25,0x0c }, - { 0x28,0x3c,0x49,0x8b }, { 0xff,0x0d,0x95,0x41 }, - { 0x39,0xa8,0x01,0x71 }, { 0x08,0x0c,0xb3,0xde }, - { 0xd8,0xb4,0xe4,0x9c }, { 0x64,0x56,0xc1,0x90 }, - { 0x7b,0xcb,0x84,0x61 }, { 0xd5,0x32,0xb6,0x70 }, - { 0x48,0x6c,0x5c,0x74 }, { 0xd0,0xb8,0x57,0x42 } - }; - -static const unsigned char T6[256][4] = - { - { 0x50,0x51,0xf4,0xa7 }, { 0x53,0x7e,0x41,0x65 }, - { 0xc3,0x1a,0x17,0xa4 }, { 0x96,0x3a,0x27,0x5e }, - { 0xcb,0x3b,0xab,0x6b }, { 0xf1,0x1f,0x9d,0x45 }, - { 0xab,0xac,0xfa,0x58 }, { 0x93,0x4b,0xe3,0x03 }, - { 0x55,0x20,0x30,0xfa }, { 0xf6,0xad,0x76,0x6d }, - { 0x91,0x88,0xcc,0x76 }, { 0x25,0xf5,0x02,0x4c }, - { 0xfc,0x4f,0xe5,0xd7 }, { 0xd7,0xc5,0x2a,0xcb }, - { 0x80,0x26,0x35,0x44 }, { 0x8f,0xb5,0x62,0xa3 }, - { 0x49,0xde,0xb1,0x5a }, { 0x67,0x25,0xba,0x1b }, - { 0x98,0x45,0xea,0x0e }, { 0xe1,0x5d,0xfe,0xc0 }, - { 0x02,0xc3,0x2f,0x75 }, { 0x12,0x81,0x4c,0xf0 }, - { 0xa3,0x8d,0x46,0x97 }, { 0xc6,0x6b,0xd3,0xf9 }, - { 0xe7,0x03,0x8f,0x5f }, { 0x95,0x15,0x92,0x9c }, - { 0xeb,0xbf,0x6d,0x7a }, { 0xda,0x95,0x52,0x59 }, - { 0x2d,0xd4,0xbe,0x83 }, { 0xd3,0x58,0x74,0x21 }, - { 0x29,0x49,0xe0,0x69 }, { 0x44,0x8e,0xc9,0xc8 }, - { 0x6a,0x75,0xc2,0x89 }, { 0x78,0xf4,0x8e,0x79 }, - { 0x6b,0x99,0x58,0x3e }, { 0xdd,0x27,0xb9,0x71 }, - { 0xb6,0xbe,0xe1,0x4f }, { 0x17,0xf0,0x88,0xad }, - { 0x66,0xc9,0x20,0xac }, { 0xb4,0x7d,0xce,0x3a }, - { 0x18,0x63,0xdf,0x4a }, { 0x82,0xe5,0x1a,0x31 }, - { 0x60,0x97,0x51,0x33 }, { 0x45,0x62,0x53,0x7f }, - { 0xe0,0xb1,0x64,0x77 }, { 0x84,0xbb,0x6b,0xae }, - { 0x1c,0xfe,0x81,0xa0 }, { 0x94,0xf9,0x08,0x2b }, - { 0x58,0x70,0x48,0x68 }, { 0x19,0x8f,0x45,0xfd }, - { 0x87,0x94,0xde,0x6c }, { 0xb7,0x52,0x7b,0xf8 }, - { 0x23,0xab,0x73,0xd3 }, { 0xe2,0x72,0x4b,0x02 }, - { 0x57,0xe3,0x1f,0x8f }, { 0x2a,0x66,0x55,0xab }, - { 0x07,0xb2,0xeb,0x28 }, { 0x03,0x2f,0xb5,0xc2 }, - { 0x9a,0x86,0xc5,0x7b }, { 0xa5,0xd3,0x37,0x08 }, - { 0xf2,0x30,0x28,0x87 }, { 0xb2,0x23,0xbf,0xa5 }, - { 0xba,0x02,0x03,0x6a }, { 0x5c,0xed,0x16,0x82 }, - { 0x2b,0x8a,0xcf,0x1c }, { 0x92,0xa7,0x79,0xb4 }, - { 0xf0,0xf3,0x07,0xf2 }, { 0xa1,0x4e,0x69,0xe2 }, - { 0xcd,0x65,0xda,0xf4 }, { 0xd5,0x06,0x05,0xbe }, - { 0x1f,0xd1,0x34,0x62 }, { 0x8a,0xc4,0xa6,0xfe }, - { 0x9d,0x34,0x2e,0x53 }, { 0xa0,0xa2,0xf3,0x55 }, - { 0x32,0x05,0x8a,0xe1 }, { 0x75,0xa4,0xf6,0xeb }, - { 0x39,0x0b,0x83,0xec }, { 0xaa,0x40,0x60,0xef }, - { 0x06,0x5e,0x71,0x9f }, { 0x51,0xbd,0x6e,0x10 }, - { 0xf9,0x3e,0x21,0x8a }, { 0x3d,0x96,0xdd,0x06 }, - { 0xae,0xdd,0x3e,0x05 }, { 0x46,0x4d,0xe6,0xbd }, - { 0xb5,0x91,0x54,0x8d }, { 0x05,0x71,0xc4,0x5d }, - { 0x6f,0x04,0x06,0xd4 }, { 0xff,0x60,0x50,0x15 }, - { 0x24,0x19,0x98,0xfb }, { 0x97,0xd6,0xbd,0xe9 }, - { 0xcc,0x89,0x40,0x43 }, { 0x77,0x67,0xd9,0x9e }, - { 0xbd,0xb0,0xe8,0x42 }, { 0x88,0x07,0x89,0x8b }, - { 0x38,0xe7,0x19,0x5b }, { 0xdb,0x79,0xc8,0xee }, - { 0x47,0xa1,0x7c,0x0a }, { 0xe9,0x7c,0x42,0x0f }, - { 0xc9,0xf8,0x84,0x1e }, { 0x00,0x00,0x00,0x00 }, - { 0x83,0x09,0x80,0x86 }, { 0x48,0x32,0x2b,0xed }, - { 0xac,0x1e,0x11,0x70 }, { 0x4e,0x6c,0x5a,0x72 }, - { 0xfb,0xfd,0x0e,0xff }, { 0x56,0x0f,0x85,0x38 }, - { 0x1e,0x3d,0xae,0xd5 }, { 0x27,0x36,0x2d,0x39 }, - { 0x64,0x0a,0x0f,0xd9 }, { 0x21,0x68,0x5c,0xa6 }, - { 0xd1,0x9b,0x5b,0x54 }, { 0x3a,0x24,0x36,0x2e }, - { 0xb1,0x0c,0x0a,0x67 }, { 0x0f,0x93,0x57,0xe7 }, - { 0xd2,0xb4,0xee,0x96 }, { 0x9e,0x1b,0x9b,0x91 }, - { 0x4f,0x80,0xc0,0xc5 }, { 0xa2,0x61,0xdc,0x20 }, - { 0x69,0x5a,0x77,0x4b }, { 0x16,0x1c,0x12,0x1a }, - { 0x0a,0xe2,0x93,0xba }, { 0xe5,0xc0,0xa0,0x2a }, - { 0x43,0x3c,0x22,0xe0 }, { 0x1d,0x12,0x1b,0x17 }, - { 0x0b,0x0e,0x09,0x0d }, { 0xad,0xf2,0x8b,0xc7 }, - { 0xb9,0x2d,0xb6,0xa8 }, { 0xc8,0x14,0x1e,0xa9 }, - { 0x85,0x57,0xf1,0x19 }, { 0x4c,0xaf,0x75,0x07 }, - { 0xbb,0xee,0x99,0xdd }, { 0xfd,0xa3,0x7f,0x60 }, - { 0x9f,0xf7,0x01,0x26 }, { 0xbc,0x5c,0x72,0xf5 }, - { 0xc5,0x44,0x66,0x3b }, { 0x34,0x5b,0xfb,0x7e }, - { 0x76,0x8b,0x43,0x29 }, { 0xdc,0xcb,0x23,0xc6 }, - { 0x68,0xb6,0xed,0xfc }, { 0x63,0xb8,0xe4,0xf1 }, - { 0xca,0xd7,0x31,0xdc }, { 0x10,0x42,0x63,0x85 }, - { 0x40,0x13,0x97,0x22 }, { 0x20,0x84,0xc6,0x11 }, - { 0x7d,0x85,0x4a,0x24 }, { 0xf8,0xd2,0xbb,0x3d }, - { 0x11,0xae,0xf9,0x32 }, { 0x6d,0xc7,0x29,0xa1 }, - { 0x4b,0x1d,0x9e,0x2f }, { 0xf3,0xdc,0xb2,0x30 }, - { 0xec,0x0d,0x86,0x52 }, { 0xd0,0x77,0xc1,0xe3 }, - { 0x6c,0x2b,0xb3,0x16 }, { 0x99,0xa9,0x70,0xb9 }, - { 0xfa,0x11,0x94,0x48 }, { 0x22,0x47,0xe9,0x64 }, - { 0xc4,0xa8,0xfc,0x8c }, { 0x1a,0xa0,0xf0,0x3f }, - { 0xd8,0x56,0x7d,0x2c }, { 0xef,0x22,0x33,0x90 }, - { 0xc7,0x87,0x49,0x4e }, { 0xc1,0xd9,0x38,0xd1 }, - { 0xfe,0x8c,0xca,0xa2 }, { 0x36,0x98,0xd4,0x0b }, - { 0xcf,0xa6,0xf5,0x81 }, { 0x28,0xa5,0x7a,0xde }, - { 0x26,0xda,0xb7,0x8e }, { 0xa4,0x3f,0xad,0xbf }, - { 0xe4,0x2c,0x3a,0x9d }, { 0x0d,0x50,0x78,0x92 }, - { 0x9b,0x6a,0x5f,0xcc }, { 0x62,0x54,0x7e,0x46 }, - { 0xc2,0xf6,0x8d,0x13 }, { 0xe8,0x90,0xd8,0xb8 }, - { 0x5e,0x2e,0x39,0xf7 }, { 0xf5,0x82,0xc3,0xaf }, - { 0xbe,0x9f,0x5d,0x80 }, { 0x7c,0x69,0xd0,0x93 }, - { 0xa9,0x6f,0xd5,0x2d }, { 0xb3,0xcf,0x25,0x12 }, - { 0x3b,0xc8,0xac,0x99 }, { 0xa7,0x10,0x18,0x7d }, - { 0x6e,0xe8,0x9c,0x63 }, { 0x7b,0xdb,0x3b,0xbb }, - { 0x09,0xcd,0x26,0x78 }, { 0xf4,0x6e,0x59,0x18 }, - { 0x01,0xec,0x9a,0xb7 }, { 0xa8,0x83,0x4f,0x9a }, - { 0x65,0xe6,0x95,0x6e }, { 0x7e,0xaa,0xff,0xe6 }, - { 0x08,0x21,0xbc,0xcf }, { 0xe6,0xef,0x15,0xe8 }, - { 0xd9,0xba,0xe7,0x9b }, { 0xce,0x4a,0x6f,0x36 }, - { 0xd4,0xea,0x9f,0x09 }, { 0xd6,0x29,0xb0,0x7c }, - { 0xaf,0x31,0xa4,0xb2 }, { 0x31,0x2a,0x3f,0x23 }, - { 0x30,0xc6,0xa5,0x94 }, { 0xc0,0x35,0xa2,0x66 }, - { 0x37,0x74,0x4e,0xbc }, { 0xa6,0xfc,0x82,0xca }, - { 0xb0,0xe0,0x90,0xd0 }, { 0x15,0x33,0xa7,0xd8 }, - { 0x4a,0xf1,0x04,0x98 }, { 0xf7,0x41,0xec,0xda }, - { 0x0e,0x7f,0xcd,0x50 }, { 0x2f,0x17,0x91,0xf6 }, - { 0x8d,0x76,0x4d,0xd6 }, { 0x4d,0x43,0xef,0xb0 }, - { 0x54,0xcc,0xaa,0x4d }, { 0xdf,0xe4,0x96,0x04 }, - { 0xe3,0x9e,0xd1,0xb5 }, { 0x1b,0x4c,0x6a,0x88 }, - { 0xb8,0xc1,0x2c,0x1f }, { 0x7f,0x46,0x65,0x51 }, - { 0x04,0x9d,0x5e,0xea }, { 0x5d,0x01,0x8c,0x35 }, - { 0x73,0xfa,0x87,0x74 }, { 0x2e,0xfb,0x0b,0x41 }, - { 0x5a,0xb3,0x67,0x1d }, { 0x52,0x92,0xdb,0xd2 }, - { 0x33,0xe9,0x10,0x56 }, { 0x13,0x6d,0xd6,0x47 }, - { 0x8c,0x9a,0xd7,0x61 }, { 0x7a,0x37,0xa1,0x0c }, - { 0x8e,0x59,0xf8,0x14 }, { 0x89,0xeb,0x13,0x3c }, - { 0xee,0xce,0xa9,0x27 }, { 0x35,0xb7,0x61,0xc9 }, - { 0xed,0xe1,0x1c,0xe5 }, { 0x3c,0x7a,0x47,0xb1 }, - { 0x59,0x9c,0xd2,0xdf }, { 0x3f,0x55,0xf2,0x73 }, - { 0x79,0x18,0x14,0xce }, { 0xbf,0x73,0xc7,0x37 }, - { 0xea,0x53,0xf7,0xcd }, { 0x5b,0x5f,0xfd,0xaa }, - { 0x14,0xdf,0x3d,0x6f }, { 0x86,0x78,0x44,0xdb }, - { 0x81,0xca,0xaf,0xf3 }, { 0x3e,0xb9,0x68,0xc4 }, - { 0x2c,0x38,0x24,0x34 }, { 0x5f,0xc2,0xa3,0x40 }, - { 0x72,0x16,0x1d,0xc3 }, { 0x0c,0xbc,0xe2,0x25 }, - { 0x8b,0x28,0x3c,0x49 }, { 0x41,0xff,0x0d,0x95 }, - { 0x71,0x39,0xa8,0x01 }, { 0xde,0x08,0x0c,0xb3 }, - { 0x9c,0xd8,0xb4,0xe4 }, { 0x90,0x64,0x56,0xc1 }, - { 0x61,0x7b,0xcb,0x84 }, { 0x70,0xd5,0x32,0xb6 }, - { 0x74,0x48,0x6c,0x5c }, { 0x42,0xd0,0xb8,0x57 } - }; - -static const unsigned char T7[256][4] = - { - { 0xa7,0x50,0x51,0xf4 }, { 0x65,0x53,0x7e,0x41 }, - { 0xa4,0xc3,0x1a,0x17 }, { 0x5e,0x96,0x3a,0x27 }, - { 0x6b,0xcb,0x3b,0xab }, { 0x45,0xf1,0x1f,0x9d }, - { 0x58,0xab,0xac,0xfa }, { 0x03,0x93,0x4b,0xe3 }, - { 0xfa,0x55,0x20,0x30 }, { 0x6d,0xf6,0xad,0x76 }, - { 0x76,0x91,0x88,0xcc }, { 0x4c,0x25,0xf5,0x02 }, - { 0xd7,0xfc,0x4f,0xe5 }, { 0xcb,0xd7,0xc5,0x2a }, - { 0x44,0x80,0x26,0x35 }, { 0xa3,0x8f,0xb5,0x62 }, - { 0x5a,0x49,0xde,0xb1 }, { 0x1b,0x67,0x25,0xba }, - { 0x0e,0x98,0x45,0xea }, { 0xc0,0xe1,0x5d,0xfe }, - { 0x75,0x02,0xc3,0x2f }, { 0xf0,0x12,0x81,0x4c }, - { 0x97,0xa3,0x8d,0x46 }, { 0xf9,0xc6,0x6b,0xd3 }, - { 0x5f,0xe7,0x03,0x8f }, { 0x9c,0x95,0x15,0x92 }, - { 0x7a,0xeb,0xbf,0x6d }, { 0x59,0xda,0x95,0x52 }, - { 0x83,0x2d,0xd4,0xbe }, { 0x21,0xd3,0x58,0x74 }, - { 0x69,0x29,0x49,0xe0 }, { 0xc8,0x44,0x8e,0xc9 }, - { 0x89,0x6a,0x75,0xc2 }, { 0x79,0x78,0xf4,0x8e }, - { 0x3e,0x6b,0x99,0x58 }, { 0x71,0xdd,0x27,0xb9 }, - { 0x4f,0xb6,0xbe,0xe1 }, { 0xad,0x17,0xf0,0x88 }, - { 0xac,0x66,0xc9,0x20 }, { 0x3a,0xb4,0x7d,0xce }, - { 0x4a,0x18,0x63,0xdf }, { 0x31,0x82,0xe5,0x1a }, - { 0x33,0x60,0x97,0x51 }, { 0x7f,0x45,0x62,0x53 }, - { 0x77,0xe0,0xb1,0x64 }, { 0xae,0x84,0xbb,0x6b }, - { 0xa0,0x1c,0xfe,0x81 }, { 0x2b,0x94,0xf9,0x08 }, - { 0x68,0x58,0x70,0x48 }, { 0xfd,0x19,0x8f,0x45 }, - { 0x6c,0x87,0x94,0xde }, { 0xf8,0xb7,0x52,0x7b }, - { 0xd3,0x23,0xab,0x73 }, { 0x02,0xe2,0x72,0x4b }, - { 0x8f,0x57,0xe3,0x1f }, { 0xab,0x2a,0x66,0x55 }, - { 0x28,0x07,0xb2,0xeb }, { 0xc2,0x03,0x2f,0xb5 }, - { 0x7b,0x9a,0x86,0xc5 }, { 0x08,0xa5,0xd3,0x37 }, - { 0x87,0xf2,0x30,0x28 }, { 0xa5,0xb2,0x23,0xbf }, - { 0x6a,0xba,0x02,0x03 }, { 0x82,0x5c,0xed,0x16 }, - { 0x1c,0x2b,0x8a,0xcf }, { 0xb4,0x92,0xa7,0x79 }, - { 0xf2,0xf0,0xf3,0x07 }, { 0xe2,0xa1,0x4e,0x69 }, - { 0xf4,0xcd,0x65,0xda }, { 0xbe,0xd5,0x06,0x05 }, - { 0x62,0x1f,0xd1,0x34 }, { 0xfe,0x8a,0xc4,0xa6 }, - { 0x53,0x9d,0x34,0x2e }, { 0x55,0xa0,0xa2,0xf3 }, - { 0xe1,0x32,0x05,0x8a }, { 0xeb,0x75,0xa4,0xf6 }, - { 0xec,0x39,0x0b,0x83 }, { 0xef,0xaa,0x40,0x60 }, - { 0x9f,0x06,0x5e,0x71 }, { 0x10,0x51,0xbd,0x6e }, - { 0x8a,0xf9,0x3e,0x21 }, { 0x06,0x3d,0x96,0xdd }, - { 0x05,0xae,0xdd,0x3e }, { 0xbd,0x46,0x4d,0xe6 }, - { 0x8d,0xb5,0x91,0x54 }, { 0x5d,0x05,0x71,0xc4 }, - { 0xd4,0x6f,0x04,0x06 }, { 0x15,0xff,0x60,0x50 }, - { 0xfb,0x24,0x19,0x98 }, { 0xe9,0x97,0xd6,0xbd }, - { 0x43,0xcc,0x89,0x40 }, { 0x9e,0x77,0x67,0xd9 }, - { 0x42,0xbd,0xb0,0xe8 }, { 0x8b,0x88,0x07,0x89 }, - { 0x5b,0x38,0xe7,0x19 }, { 0xee,0xdb,0x79,0xc8 }, - { 0x0a,0x47,0xa1,0x7c }, { 0x0f,0xe9,0x7c,0x42 }, - { 0x1e,0xc9,0xf8,0x84 }, { 0x00,0x00,0x00,0x00 }, - { 0x86,0x83,0x09,0x80 }, { 0xed,0x48,0x32,0x2b }, - { 0x70,0xac,0x1e,0x11 }, { 0x72,0x4e,0x6c,0x5a }, - { 0xff,0xfb,0xfd,0x0e }, { 0x38,0x56,0x0f,0x85 }, - { 0xd5,0x1e,0x3d,0xae }, { 0x39,0x27,0x36,0x2d }, - { 0xd9,0x64,0x0a,0x0f }, { 0xa6,0x21,0x68,0x5c }, - { 0x54,0xd1,0x9b,0x5b }, { 0x2e,0x3a,0x24,0x36 }, - { 0x67,0xb1,0x0c,0x0a }, { 0xe7,0x0f,0x93,0x57 }, - { 0x96,0xd2,0xb4,0xee }, { 0x91,0x9e,0x1b,0x9b }, - { 0xc5,0x4f,0x80,0xc0 }, { 0x20,0xa2,0x61,0xdc }, - { 0x4b,0x69,0x5a,0x77 }, { 0x1a,0x16,0x1c,0x12 }, - { 0xba,0x0a,0xe2,0x93 }, { 0x2a,0xe5,0xc0,0xa0 }, - { 0xe0,0x43,0x3c,0x22 }, { 0x17,0x1d,0x12,0x1b }, - { 0x0d,0x0b,0x0e,0x09 }, { 0xc7,0xad,0xf2,0x8b }, - { 0xa8,0xb9,0x2d,0xb6 }, { 0xa9,0xc8,0x14,0x1e }, - { 0x19,0x85,0x57,0xf1 }, { 0x07,0x4c,0xaf,0x75 }, - { 0xdd,0xbb,0xee,0x99 }, { 0x60,0xfd,0xa3,0x7f }, - { 0x26,0x9f,0xf7,0x01 }, { 0xf5,0xbc,0x5c,0x72 }, - { 0x3b,0xc5,0x44,0x66 }, { 0x7e,0x34,0x5b,0xfb }, - { 0x29,0x76,0x8b,0x43 }, { 0xc6,0xdc,0xcb,0x23 }, - { 0xfc,0x68,0xb6,0xed }, { 0xf1,0x63,0xb8,0xe4 }, - { 0xdc,0xca,0xd7,0x31 }, { 0x85,0x10,0x42,0x63 }, - { 0x22,0x40,0x13,0x97 }, { 0x11,0x20,0x84,0xc6 }, - { 0x24,0x7d,0x85,0x4a }, { 0x3d,0xf8,0xd2,0xbb }, - { 0x32,0x11,0xae,0xf9 }, { 0xa1,0x6d,0xc7,0x29 }, - { 0x2f,0x4b,0x1d,0x9e }, { 0x30,0xf3,0xdc,0xb2 }, - { 0x52,0xec,0x0d,0x86 }, { 0xe3,0xd0,0x77,0xc1 }, - { 0x16,0x6c,0x2b,0xb3 }, { 0xb9,0x99,0xa9,0x70 }, - { 0x48,0xfa,0x11,0x94 }, { 0x64,0x22,0x47,0xe9 }, - { 0x8c,0xc4,0xa8,0xfc }, { 0x3f,0x1a,0xa0,0xf0 }, - { 0x2c,0xd8,0x56,0x7d }, { 0x90,0xef,0x22,0x33 }, - { 0x4e,0xc7,0x87,0x49 }, { 0xd1,0xc1,0xd9,0x38 }, - { 0xa2,0xfe,0x8c,0xca }, { 0x0b,0x36,0x98,0xd4 }, - { 0x81,0xcf,0xa6,0xf5 }, { 0xde,0x28,0xa5,0x7a }, - { 0x8e,0x26,0xda,0xb7 }, { 0xbf,0xa4,0x3f,0xad }, - { 0x9d,0xe4,0x2c,0x3a }, { 0x92,0x0d,0x50,0x78 }, - { 0xcc,0x9b,0x6a,0x5f }, { 0x46,0x62,0x54,0x7e }, - { 0x13,0xc2,0xf6,0x8d }, { 0xb8,0xe8,0x90,0xd8 }, - { 0xf7,0x5e,0x2e,0x39 }, { 0xaf,0xf5,0x82,0xc3 }, - { 0x80,0xbe,0x9f,0x5d }, { 0x93,0x7c,0x69,0xd0 }, - { 0x2d,0xa9,0x6f,0xd5 }, { 0x12,0xb3,0xcf,0x25 }, - { 0x99,0x3b,0xc8,0xac }, { 0x7d,0xa7,0x10,0x18 }, - { 0x63,0x6e,0xe8,0x9c }, { 0xbb,0x7b,0xdb,0x3b }, - { 0x78,0x09,0xcd,0x26 }, { 0x18,0xf4,0x6e,0x59 }, - { 0xb7,0x01,0xec,0x9a }, { 0x9a,0xa8,0x83,0x4f }, - { 0x6e,0x65,0xe6,0x95 }, { 0xe6,0x7e,0xaa,0xff }, - { 0xcf,0x08,0x21,0xbc }, { 0xe8,0xe6,0xef,0x15 }, - { 0x9b,0xd9,0xba,0xe7 }, { 0x36,0xce,0x4a,0x6f }, - { 0x09,0xd4,0xea,0x9f }, { 0x7c,0xd6,0x29,0xb0 }, - { 0xb2,0xaf,0x31,0xa4 }, { 0x23,0x31,0x2a,0x3f }, - { 0x94,0x30,0xc6,0xa5 }, { 0x66,0xc0,0x35,0xa2 }, - { 0xbc,0x37,0x74,0x4e }, { 0xca,0xa6,0xfc,0x82 }, - { 0xd0,0xb0,0xe0,0x90 }, { 0xd8,0x15,0x33,0xa7 }, - { 0x98,0x4a,0xf1,0x04 }, { 0xda,0xf7,0x41,0xec }, - { 0x50,0x0e,0x7f,0xcd }, { 0xf6,0x2f,0x17,0x91 }, - { 0xd6,0x8d,0x76,0x4d }, { 0xb0,0x4d,0x43,0xef }, - { 0x4d,0x54,0xcc,0xaa }, { 0x04,0xdf,0xe4,0x96 }, - { 0xb5,0xe3,0x9e,0xd1 }, { 0x88,0x1b,0x4c,0x6a }, - { 0x1f,0xb8,0xc1,0x2c }, { 0x51,0x7f,0x46,0x65 }, - { 0xea,0x04,0x9d,0x5e }, { 0x35,0x5d,0x01,0x8c }, - { 0x74,0x73,0xfa,0x87 }, { 0x41,0x2e,0xfb,0x0b }, - { 0x1d,0x5a,0xb3,0x67 }, { 0xd2,0x52,0x92,0xdb }, - { 0x56,0x33,0xe9,0x10 }, { 0x47,0x13,0x6d,0xd6 }, - { 0x61,0x8c,0x9a,0xd7 }, { 0x0c,0x7a,0x37,0xa1 }, - { 0x14,0x8e,0x59,0xf8 }, { 0x3c,0x89,0xeb,0x13 }, - { 0x27,0xee,0xce,0xa9 }, { 0xc9,0x35,0xb7,0x61 }, - { 0xe5,0xed,0xe1,0x1c }, { 0xb1,0x3c,0x7a,0x47 }, - { 0xdf,0x59,0x9c,0xd2 }, { 0x73,0x3f,0x55,0xf2 }, - { 0xce,0x79,0x18,0x14 }, { 0x37,0xbf,0x73,0xc7 }, - { 0xcd,0xea,0x53,0xf7 }, { 0xaa,0x5b,0x5f,0xfd }, - { 0x6f,0x14,0xdf,0x3d }, { 0xdb,0x86,0x78,0x44 }, - { 0xf3,0x81,0xca,0xaf }, { 0xc4,0x3e,0xb9,0x68 }, - { 0x34,0x2c,0x38,0x24 }, { 0x40,0x5f,0xc2,0xa3 }, - { 0xc3,0x72,0x16,0x1d }, { 0x25,0x0c,0xbc,0xe2 }, - { 0x49,0x8b,0x28,0x3c }, { 0x95,0x41,0xff,0x0d }, - { 0x01,0x71,0x39,0xa8 }, { 0xb3,0xde,0x08,0x0c }, - { 0xe4,0x9c,0xd8,0xb4 }, { 0xc1,0x90,0x64,0x56 }, - { 0x84,0x61,0x7b,0xcb }, { 0xb6,0x70,0xd5,0x32 }, - { 0x5c,0x74,0x48,0x6c }, { 0x57,0x42,0xd0,0xb8 } - }; - -static const unsigned char T8[256][4] = - { - { 0xf4,0xa7,0x50,0x51 }, { 0x41,0x65,0x53,0x7e }, - { 0x17,0xa4,0xc3,0x1a }, { 0x27,0x5e,0x96,0x3a }, - { 0xab,0x6b,0xcb,0x3b }, { 0x9d,0x45,0xf1,0x1f }, - { 0xfa,0x58,0xab,0xac }, { 0xe3,0x03,0x93,0x4b }, - { 0x30,0xfa,0x55,0x20 }, { 0x76,0x6d,0xf6,0xad }, - { 0xcc,0x76,0x91,0x88 }, { 0x02,0x4c,0x25,0xf5 }, - { 0xe5,0xd7,0xfc,0x4f }, { 0x2a,0xcb,0xd7,0xc5 }, - { 0x35,0x44,0x80,0x26 }, { 0x62,0xa3,0x8f,0xb5 }, - { 0xb1,0x5a,0x49,0xde }, { 0xba,0x1b,0x67,0x25 }, - { 0xea,0x0e,0x98,0x45 }, { 0xfe,0xc0,0xe1,0x5d }, - { 0x2f,0x75,0x02,0xc3 }, { 0x4c,0xf0,0x12,0x81 }, - { 0x46,0x97,0xa3,0x8d }, { 0xd3,0xf9,0xc6,0x6b }, - { 0x8f,0x5f,0xe7,0x03 }, { 0x92,0x9c,0x95,0x15 }, - { 0x6d,0x7a,0xeb,0xbf }, { 0x52,0x59,0xda,0x95 }, - { 0xbe,0x83,0x2d,0xd4 }, { 0x74,0x21,0xd3,0x58 }, - { 0xe0,0x69,0x29,0x49 }, { 0xc9,0xc8,0x44,0x8e }, - { 0xc2,0x89,0x6a,0x75 }, { 0x8e,0x79,0x78,0xf4 }, - { 0x58,0x3e,0x6b,0x99 }, { 0xb9,0x71,0xdd,0x27 }, - { 0xe1,0x4f,0xb6,0xbe }, { 0x88,0xad,0x17,0xf0 }, - { 0x20,0xac,0x66,0xc9 }, { 0xce,0x3a,0xb4,0x7d }, - { 0xdf,0x4a,0x18,0x63 }, { 0x1a,0x31,0x82,0xe5 }, - { 0x51,0x33,0x60,0x97 }, { 0x53,0x7f,0x45,0x62 }, - { 0x64,0x77,0xe0,0xb1 }, { 0x6b,0xae,0x84,0xbb }, - { 0x81,0xa0,0x1c,0xfe }, { 0x08,0x2b,0x94,0xf9 }, - { 0x48,0x68,0x58,0x70 }, { 0x45,0xfd,0x19,0x8f }, - { 0xde,0x6c,0x87,0x94 }, { 0x7b,0xf8,0xb7,0x52 }, - { 0x73,0xd3,0x23,0xab }, { 0x4b,0x02,0xe2,0x72 }, - { 0x1f,0x8f,0x57,0xe3 }, { 0x55,0xab,0x2a,0x66 }, - { 0xeb,0x28,0x07,0xb2 }, { 0xb5,0xc2,0x03,0x2f }, - { 0xc5,0x7b,0x9a,0x86 }, { 0x37,0x08,0xa5,0xd3 }, - { 0x28,0x87,0xf2,0x30 }, { 0xbf,0xa5,0xb2,0x23 }, - { 0x03,0x6a,0xba,0x02 }, { 0x16,0x82,0x5c,0xed }, - { 0xcf,0x1c,0x2b,0x8a }, { 0x79,0xb4,0x92,0xa7 }, - { 0x07,0xf2,0xf0,0xf3 }, { 0x69,0xe2,0xa1,0x4e }, - { 0xda,0xf4,0xcd,0x65 }, { 0x05,0xbe,0xd5,0x06 }, - { 0x34,0x62,0x1f,0xd1 }, { 0xa6,0xfe,0x8a,0xc4 }, - { 0x2e,0x53,0x9d,0x34 }, { 0xf3,0x55,0xa0,0xa2 }, - { 0x8a,0xe1,0x32,0x05 }, { 0xf6,0xeb,0x75,0xa4 }, - { 0x83,0xec,0x39,0x0b }, { 0x60,0xef,0xaa,0x40 }, - { 0x71,0x9f,0x06,0x5e }, { 0x6e,0x10,0x51,0xbd }, - { 0x21,0x8a,0xf9,0x3e }, { 0xdd,0x06,0x3d,0x96 }, - { 0x3e,0x05,0xae,0xdd }, { 0xe6,0xbd,0x46,0x4d }, - { 0x54,0x8d,0xb5,0x91 }, { 0xc4,0x5d,0x05,0x71 }, - { 0x06,0xd4,0x6f,0x04 }, { 0x50,0x15,0xff,0x60 }, - { 0x98,0xfb,0x24,0x19 }, { 0xbd,0xe9,0x97,0xd6 }, - { 0x40,0x43,0xcc,0x89 }, { 0xd9,0x9e,0x77,0x67 }, - { 0xe8,0x42,0xbd,0xb0 }, { 0x89,0x8b,0x88,0x07 }, - { 0x19,0x5b,0x38,0xe7 }, { 0xc8,0xee,0xdb,0x79 }, - { 0x7c,0x0a,0x47,0xa1 }, { 0x42,0x0f,0xe9,0x7c }, - { 0x84,0x1e,0xc9,0xf8 }, { 0x00,0x00,0x00,0x00 }, - { 0x80,0x86,0x83,0x09 }, { 0x2b,0xed,0x48,0x32 }, - { 0x11,0x70,0xac,0x1e }, { 0x5a,0x72,0x4e,0x6c }, - { 0x0e,0xff,0xfb,0xfd }, { 0x85,0x38,0x56,0x0f }, - { 0xae,0xd5,0x1e,0x3d }, { 0x2d,0x39,0x27,0x36 }, - { 0x0f,0xd9,0x64,0x0a }, { 0x5c,0xa6,0x21,0x68 }, - { 0x5b,0x54,0xd1,0x9b }, { 0x36,0x2e,0x3a,0x24 }, - { 0x0a,0x67,0xb1,0x0c }, { 0x57,0xe7,0x0f,0x93 }, - { 0xee,0x96,0xd2,0xb4 }, { 0x9b,0x91,0x9e,0x1b }, - { 0xc0,0xc5,0x4f,0x80 }, { 0xdc,0x20,0xa2,0x61 }, - { 0x77,0x4b,0x69,0x5a }, { 0x12,0x1a,0x16,0x1c }, - { 0x93,0xba,0x0a,0xe2 }, { 0xa0,0x2a,0xe5,0xc0 }, - { 0x22,0xe0,0x43,0x3c }, { 0x1b,0x17,0x1d,0x12 }, - { 0x09,0x0d,0x0b,0x0e }, { 0x8b,0xc7,0xad,0xf2 }, - { 0xb6,0xa8,0xb9,0x2d }, { 0x1e,0xa9,0xc8,0x14 }, - { 0xf1,0x19,0x85,0x57 }, { 0x75,0x07,0x4c,0xaf }, - { 0x99,0xdd,0xbb,0xee }, { 0x7f,0x60,0xfd,0xa3 }, - { 0x01,0x26,0x9f,0xf7 }, { 0x72,0xf5,0xbc,0x5c }, - { 0x66,0x3b,0xc5,0x44 }, { 0xfb,0x7e,0x34,0x5b }, - { 0x43,0x29,0x76,0x8b }, { 0x23,0xc6,0xdc,0xcb }, - { 0xed,0xfc,0x68,0xb6 }, { 0xe4,0xf1,0x63,0xb8 }, - { 0x31,0xdc,0xca,0xd7 }, { 0x63,0x85,0x10,0x42 }, - { 0x97,0x22,0x40,0x13 }, { 0xc6,0x11,0x20,0x84 }, - { 0x4a,0x24,0x7d,0x85 }, { 0xbb,0x3d,0xf8,0xd2 }, - { 0xf9,0x32,0x11,0xae }, { 0x29,0xa1,0x6d,0xc7 }, - { 0x9e,0x2f,0x4b,0x1d }, { 0xb2,0x30,0xf3,0xdc }, - { 0x86,0x52,0xec,0x0d }, { 0xc1,0xe3,0xd0,0x77 }, - { 0xb3,0x16,0x6c,0x2b }, { 0x70,0xb9,0x99,0xa9 }, - { 0x94,0x48,0xfa,0x11 }, { 0xe9,0x64,0x22,0x47 }, - { 0xfc,0x8c,0xc4,0xa8 }, { 0xf0,0x3f,0x1a,0xa0 }, - { 0x7d,0x2c,0xd8,0x56 }, { 0x33,0x90,0xef,0x22 }, - { 0x49,0x4e,0xc7,0x87 }, { 0x38,0xd1,0xc1,0xd9 }, - { 0xca,0xa2,0xfe,0x8c }, { 0xd4,0x0b,0x36,0x98 }, - { 0xf5,0x81,0xcf,0xa6 }, { 0x7a,0xde,0x28,0xa5 }, - { 0xb7,0x8e,0x26,0xda }, { 0xad,0xbf,0xa4,0x3f }, - { 0x3a,0x9d,0xe4,0x2c }, { 0x78,0x92,0x0d,0x50 }, - { 0x5f,0xcc,0x9b,0x6a }, { 0x7e,0x46,0x62,0x54 }, - { 0x8d,0x13,0xc2,0xf6 }, { 0xd8,0xb8,0xe8,0x90 }, - { 0x39,0xf7,0x5e,0x2e }, { 0xc3,0xaf,0xf5,0x82 }, - { 0x5d,0x80,0xbe,0x9f }, { 0xd0,0x93,0x7c,0x69 }, - { 0xd5,0x2d,0xa9,0x6f }, { 0x25,0x12,0xb3,0xcf }, - { 0xac,0x99,0x3b,0xc8 }, { 0x18,0x7d,0xa7,0x10 }, - { 0x9c,0x63,0x6e,0xe8 }, { 0x3b,0xbb,0x7b,0xdb }, - { 0x26,0x78,0x09,0xcd }, { 0x59,0x18,0xf4,0x6e }, - { 0x9a,0xb7,0x01,0xec }, { 0x4f,0x9a,0xa8,0x83 }, - { 0x95,0x6e,0x65,0xe6 }, { 0xff,0xe6,0x7e,0xaa }, - { 0xbc,0xcf,0x08,0x21 }, { 0x15,0xe8,0xe6,0xef }, - { 0xe7,0x9b,0xd9,0xba }, { 0x6f,0x36,0xce,0x4a }, - { 0x9f,0x09,0xd4,0xea }, { 0xb0,0x7c,0xd6,0x29 }, - { 0xa4,0xb2,0xaf,0x31 }, { 0x3f,0x23,0x31,0x2a }, - { 0xa5,0x94,0x30,0xc6 }, { 0xa2,0x66,0xc0,0x35 }, - { 0x4e,0xbc,0x37,0x74 }, { 0x82,0xca,0xa6,0xfc }, - { 0x90,0xd0,0xb0,0xe0 }, { 0xa7,0xd8,0x15,0x33 }, - { 0x04,0x98,0x4a,0xf1 }, { 0xec,0xda,0xf7,0x41 }, - { 0xcd,0x50,0x0e,0x7f }, { 0x91,0xf6,0x2f,0x17 }, - { 0x4d,0xd6,0x8d,0x76 }, { 0xef,0xb0,0x4d,0x43 }, - { 0xaa,0x4d,0x54,0xcc }, { 0x96,0x04,0xdf,0xe4 }, - { 0xd1,0xb5,0xe3,0x9e }, { 0x6a,0x88,0x1b,0x4c }, - { 0x2c,0x1f,0xb8,0xc1 }, { 0x65,0x51,0x7f,0x46 }, - { 0x5e,0xea,0x04,0x9d }, { 0x8c,0x35,0x5d,0x01 }, - { 0x87,0x74,0x73,0xfa }, { 0x0b,0x41,0x2e,0xfb }, - { 0x67,0x1d,0x5a,0xb3 }, { 0xdb,0xd2,0x52,0x92 }, - { 0x10,0x56,0x33,0xe9 }, { 0xd6,0x47,0x13,0x6d }, - { 0xd7,0x61,0x8c,0x9a }, { 0xa1,0x0c,0x7a,0x37 }, - { 0xf8,0x14,0x8e,0x59 }, { 0x13,0x3c,0x89,0xeb }, - { 0xa9,0x27,0xee,0xce }, { 0x61,0xc9,0x35,0xb7 }, - { 0x1c,0xe5,0xed,0xe1 }, { 0x47,0xb1,0x3c,0x7a }, - { 0xd2,0xdf,0x59,0x9c }, { 0xf2,0x73,0x3f,0x55 }, - { 0x14,0xce,0x79,0x18 }, { 0xc7,0x37,0xbf,0x73 }, - { 0xf7,0xcd,0xea,0x53 }, { 0xfd,0xaa,0x5b,0x5f }, - { 0x3d,0x6f,0x14,0xdf }, { 0x44,0xdb,0x86,0x78 }, - { 0xaf,0xf3,0x81,0xca }, { 0x68,0xc4,0x3e,0xb9 }, - { 0x24,0x34,0x2c,0x38 }, { 0xa3,0x40,0x5f,0xc2 }, - { 0x1d,0xc3,0x72,0x16 }, { 0xe2,0x25,0x0c,0xbc }, - { 0x3c,0x49,0x8b,0x28 }, { 0x0d,0x95,0x41,0xff }, - { 0xa8,0x01,0x71,0x39 }, { 0x0c,0xb3,0xde,0x08 }, - { 0xb4,0xe4,0x9c,0xd8 }, { 0x56,0xc1,0x90,0x64 }, - { 0xcb,0x84,0x61,0x7b }, { 0x32,0xb6,0x70,0xd5 }, - { 0x6c,0x5c,0x74,0x48 }, { 0xb8,0x57,0x42,0xd0 } - }; - -static const unsigned char S5[256] = - { - 0x52,0x09,0x6a,0xd5,0x30,0x36,0xa5,0x38, - 0xbf,0x40,0xa3,0x9e,0x81,0xf3,0xd7,0xfb, - 0x7c,0xe3,0x39,0x82,0x9b,0x2f,0xff,0x87, - 0x34,0x8e,0x43,0x44,0xc4,0xde,0xe9,0xcb, - 0x54,0x7b,0x94,0x32,0xa6,0xc2,0x23,0x3d, - 0xee,0x4c,0x95,0x0b,0x42,0xfa,0xc3,0x4e, - 0x08,0x2e,0xa1,0x66,0x28,0xd9,0x24,0xb2, - 0x76,0x5b,0xa2,0x49,0x6d,0x8b,0xd1,0x25, - 0x72,0xf8,0xf6,0x64,0x86,0x68,0x98,0x16, - 0xd4,0xa4,0x5c,0xcc,0x5d,0x65,0xb6,0x92, - 0x6c,0x70,0x48,0x50,0xfd,0xed,0xb9,0xda, - 0x5e,0x15,0x46,0x57,0xa7,0x8d,0x9d,0x84, - 0x90,0xd8,0xab,0x00,0x8c,0xbc,0xd3,0x0a, - 0xf7,0xe4,0x58,0x05,0xb8,0xb3,0x45,0x06, - 0xd0,0x2c,0x1e,0x8f,0xca,0x3f,0x0f,0x02, - 0xc1,0xaf,0xbd,0x03,0x01,0x13,0x8a,0x6b, - 0x3a,0x91,0x11,0x41,0x4f,0x67,0xdc,0xea, - 0x97,0xf2,0xcf,0xce,0xf0,0xb4,0xe6,0x73, - 0x96,0xac,0x74,0x22,0xe7,0xad,0x35,0x85, - 0xe2,0xf9,0x37,0xe8,0x1c,0x75,0xdf,0x6e, - 0x47,0xf1,0x1a,0x71,0x1d,0x29,0xc5,0x89, - 0x6f,0xb7,0x62,0x0e,0xaa,0x18,0xbe,0x1b, - 0xfc,0x56,0x3e,0x4b,0xc6,0xd2,0x79,0x20, - 0x9a,0xdb,0xc0,0xfe,0x78,0xcd,0x5a,0xf4, - 0x1f,0xdd,0xa8,0x33,0x88,0x07,0xc7,0x31, - 0xb1,0x12,0x10,0x59,0x27,0x80,0xec,0x5f, - 0x60,0x51,0x7f,0xa9,0x19,0xb5,0x4a,0x0d, - 0x2d,0xe5,0x7a,0x9f,0x93,0xc9,0x9c,0xef, - 0xa0,0xe0,0x3b,0x4d,0xae,0x2a,0xf5,0xb0, - 0xc8,0xeb,0xbb,0x3c,0x83,0x53,0x99,0x61, - 0x17,0x2b,0x04,0x7e,0xba,0x77,0xd6,0x26, - 0xe1,0x69,0x14,0x63,0x55,0x21,0x0c,0x7d - }; - -static const unsigned char U1[256][4] = - { - { 0x00,0x00,0x00,0x00 }, { 0x0e,0x09,0x0d,0x0b }, - { 0x1c,0x12,0x1a,0x16 }, { 0x12,0x1b,0x17,0x1d }, - { 0x38,0x24,0x34,0x2c }, { 0x36,0x2d,0x39,0x27 }, - { 0x24,0x36,0x2e,0x3a }, { 0x2a,0x3f,0x23,0x31 }, - { 0x70,0x48,0x68,0x58 }, { 0x7e,0x41,0x65,0x53 }, - { 0x6c,0x5a,0x72,0x4e }, { 0x62,0x53,0x7f,0x45 }, - { 0x48,0x6c,0x5c,0x74 }, { 0x46,0x65,0x51,0x7f }, - { 0x54,0x7e,0x46,0x62 }, { 0x5a,0x77,0x4b,0x69 }, - { 0xe0,0x90,0xd0,0xb0 }, { 0xee,0x99,0xdd,0xbb }, - { 0xfc,0x82,0xca,0xa6 }, { 0xf2,0x8b,0xc7,0xad }, - { 0xd8,0xb4,0xe4,0x9c }, { 0xd6,0xbd,0xe9,0x97 }, - { 0xc4,0xa6,0xfe,0x8a }, { 0xca,0xaf,0xf3,0x81 }, - { 0x90,0xd8,0xb8,0xe8 }, { 0x9e,0xd1,0xb5,0xe3 }, - { 0x8c,0xca,0xa2,0xfe }, { 0x82,0xc3,0xaf,0xf5 }, - { 0xa8,0xfc,0x8c,0xc4 }, { 0xa6,0xf5,0x81,0xcf }, - { 0xb4,0xee,0x96,0xd2 }, { 0xba,0xe7,0x9b,0xd9 }, - { 0xdb,0x3b,0xbb,0x7b }, { 0xd5,0x32,0xb6,0x70 }, - { 0xc7,0x29,0xa1,0x6d }, { 0xc9,0x20,0xac,0x66 }, - { 0xe3,0x1f,0x8f,0x57 }, { 0xed,0x16,0x82,0x5c }, - { 0xff,0x0d,0x95,0x41 }, { 0xf1,0x04,0x98,0x4a }, - { 0xab,0x73,0xd3,0x23 }, { 0xa5,0x7a,0xde,0x28 }, - { 0xb7,0x61,0xc9,0x35 }, { 0xb9,0x68,0xc4,0x3e }, - { 0x93,0x57,0xe7,0x0f }, { 0x9d,0x5e,0xea,0x04 }, - { 0x8f,0x45,0xfd,0x19 }, { 0x81,0x4c,0xf0,0x12 }, - { 0x3b,0xab,0x6b,0xcb }, { 0x35,0xa2,0x66,0xc0 }, - { 0x27,0xb9,0x71,0xdd }, { 0x29,0xb0,0x7c,0xd6 }, - { 0x03,0x8f,0x5f,0xe7 }, { 0x0d,0x86,0x52,0xec }, - { 0x1f,0x9d,0x45,0xf1 }, { 0x11,0x94,0x48,0xfa }, - { 0x4b,0xe3,0x03,0x93 }, { 0x45,0xea,0x0e,0x98 }, - { 0x57,0xf1,0x19,0x85 }, { 0x59,0xf8,0x14,0x8e }, - { 0x73,0xc7,0x37,0xbf }, { 0x7d,0xce,0x3a,0xb4 }, - { 0x6f,0xd5,0x2d,0xa9 }, { 0x61,0xdc,0x20,0xa2 }, - { 0xad,0x76,0x6d,0xf6 }, { 0xa3,0x7f,0x60,0xfd }, - { 0xb1,0x64,0x77,0xe0 }, { 0xbf,0x6d,0x7a,0xeb }, - { 0x95,0x52,0x59,0xda }, { 0x9b,0x5b,0x54,0xd1 }, - { 0x89,0x40,0x43,0xcc }, { 0x87,0x49,0x4e,0xc7 }, - { 0xdd,0x3e,0x05,0xae }, { 0xd3,0x37,0x08,0xa5 }, - { 0xc1,0x2c,0x1f,0xb8 }, { 0xcf,0x25,0x12,0xb3 }, - { 0xe5,0x1a,0x31,0x82 }, { 0xeb,0x13,0x3c,0x89 }, - { 0xf9,0x08,0x2b,0x94 }, { 0xf7,0x01,0x26,0x9f }, - { 0x4d,0xe6,0xbd,0x46 }, { 0x43,0xef,0xb0,0x4d }, - { 0x51,0xf4,0xa7,0x50 }, { 0x5f,0xfd,0xaa,0x5b }, - { 0x75,0xc2,0x89,0x6a }, { 0x7b,0xcb,0x84,0x61 }, - { 0x69,0xd0,0x93,0x7c }, { 0x67,0xd9,0x9e,0x77 }, - { 0x3d,0xae,0xd5,0x1e }, { 0x33,0xa7,0xd8,0x15 }, - { 0x21,0xbc,0xcf,0x08 }, { 0x2f,0xb5,0xc2,0x03 }, - { 0x05,0x8a,0xe1,0x32 }, { 0x0b,0x83,0xec,0x39 }, - { 0x19,0x98,0xfb,0x24 }, { 0x17,0x91,0xf6,0x2f }, - { 0x76,0x4d,0xd6,0x8d }, { 0x78,0x44,0xdb,0x86 }, - { 0x6a,0x5f,0xcc,0x9b }, { 0x64,0x56,0xc1,0x90 }, - { 0x4e,0x69,0xe2,0xa1 }, { 0x40,0x60,0xef,0xaa }, - { 0x52,0x7b,0xf8,0xb7 }, { 0x5c,0x72,0xf5,0xbc }, - { 0x06,0x05,0xbe,0xd5 }, { 0x08,0x0c,0xb3,0xde }, - { 0x1a,0x17,0xa4,0xc3 }, { 0x14,0x1e,0xa9,0xc8 }, - { 0x3e,0x21,0x8a,0xf9 }, { 0x30,0x28,0x87,0xf2 }, - { 0x22,0x33,0x90,0xef }, { 0x2c,0x3a,0x9d,0xe4 }, - { 0x96,0xdd,0x06,0x3d }, { 0x98,0xd4,0x0b,0x36 }, - { 0x8a,0xcf,0x1c,0x2b }, { 0x84,0xc6,0x11,0x20 }, - { 0xae,0xf9,0x32,0x11 }, { 0xa0,0xf0,0x3f,0x1a }, - { 0xb2,0xeb,0x28,0x07 }, { 0xbc,0xe2,0x25,0x0c }, - { 0xe6,0x95,0x6e,0x65 }, { 0xe8,0x9c,0x63,0x6e }, - { 0xfa,0x87,0x74,0x73 }, { 0xf4,0x8e,0x79,0x78 }, - { 0xde,0xb1,0x5a,0x49 }, { 0xd0,0xb8,0x57,0x42 }, - { 0xc2,0xa3,0x40,0x5f }, { 0xcc,0xaa,0x4d,0x54 }, - { 0x41,0xec,0xda,0xf7 }, { 0x4f,0xe5,0xd7,0xfc }, - { 0x5d,0xfe,0xc0,0xe1 }, { 0x53,0xf7,0xcd,0xea }, - { 0x79,0xc8,0xee,0xdb }, { 0x77,0xc1,0xe3,0xd0 }, - { 0x65,0xda,0xf4,0xcd }, { 0x6b,0xd3,0xf9,0xc6 }, - { 0x31,0xa4,0xb2,0xaf }, { 0x3f,0xad,0xbf,0xa4 }, - { 0x2d,0xb6,0xa8,0xb9 }, { 0x23,0xbf,0xa5,0xb2 }, - { 0x09,0x80,0x86,0x83 }, { 0x07,0x89,0x8b,0x88 }, - { 0x15,0x92,0x9c,0x95 }, { 0x1b,0x9b,0x91,0x9e }, - { 0xa1,0x7c,0x0a,0x47 }, { 0xaf,0x75,0x07,0x4c }, - { 0xbd,0x6e,0x10,0x51 }, { 0xb3,0x67,0x1d,0x5a }, - { 0x99,0x58,0x3e,0x6b }, { 0x97,0x51,0x33,0x60 }, - { 0x85,0x4a,0x24,0x7d }, { 0x8b,0x43,0x29,0x76 }, - { 0xd1,0x34,0x62,0x1f }, { 0xdf,0x3d,0x6f,0x14 }, - { 0xcd,0x26,0x78,0x09 }, { 0xc3,0x2f,0x75,0x02 }, - { 0xe9,0x10,0x56,0x33 }, { 0xe7,0x19,0x5b,0x38 }, - { 0xf5,0x02,0x4c,0x25 }, { 0xfb,0x0b,0x41,0x2e }, - { 0x9a,0xd7,0x61,0x8c }, { 0x94,0xde,0x6c,0x87 }, - { 0x86,0xc5,0x7b,0x9a }, { 0x88,0xcc,0x76,0x91 }, - { 0xa2,0xf3,0x55,0xa0 }, { 0xac,0xfa,0x58,0xab }, - { 0xbe,0xe1,0x4f,0xb6 }, { 0xb0,0xe8,0x42,0xbd }, - { 0xea,0x9f,0x09,0xd4 }, { 0xe4,0x96,0x04,0xdf }, - { 0xf6,0x8d,0x13,0xc2 }, { 0xf8,0x84,0x1e,0xc9 }, - { 0xd2,0xbb,0x3d,0xf8 }, { 0xdc,0xb2,0x30,0xf3 }, - { 0xce,0xa9,0x27,0xee }, { 0xc0,0xa0,0x2a,0xe5 }, - { 0x7a,0x47,0xb1,0x3c }, { 0x74,0x4e,0xbc,0x37 }, - { 0x66,0x55,0xab,0x2a }, { 0x68,0x5c,0xa6,0x21 }, - { 0x42,0x63,0x85,0x10 }, { 0x4c,0x6a,0x88,0x1b }, - { 0x5e,0x71,0x9f,0x06 }, { 0x50,0x78,0x92,0x0d }, - { 0x0a,0x0f,0xd9,0x64 }, { 0x04,0x06,0xd4,0x6f }, - { 0x16,0x1d,0xc3,0x72 }, { 0x18,0x14,0xce,0x79 }, - { 0x32,0x2b,0xed,0x48 }, { 0x3c,0x22,0xe0,0x43 }, - { 0x2e,0x39,0xf7,0x5e }, { 0x20,0x30,0xfa,0x55 }, - { 0xec,0x9a,0xb7,0x01 }, { 0xe2,0x93,0xba,0x0a }, - { 0xf0,0x88,0xad,0x17 }, { 0xfe,0x81,0xa0,0x1c }, - { 0xd4,0xbe,0x83,0x2d }, { 0xda,0xb7,0x8e,0x26 }, - { 0xc8,0xac,0x99,0x3b }, { 0xc6,0xa5,0x94,0x30 }, - { 0x9c,0xd2,0xdf,0x59 }, { 0x92,0xdb,0xd2,0x52 }, - { 0x80,0xc0,0xc5,0x4f }, { 0x8e,0xc9,0xc8,0x44 }, - { 0xa4,0xf6,0xeb,0x75 }, { 0xaa,0xff,0xe6,0x7e }, - { 0xb8,0xe4,0xf1,0x63 }, { 0xb6,0xed,0xfc,0x68 }, - { 0x0c,0x0a,0x67,0xb1 }, { 0x02,0x03,0x6a,0xba }, - { 0x10,0x18,0x7d,0xa7 }, { 0x1e,0x11,0x70,0xac }, - { 0x34,0x2e,0x53,0x9d }, { 0x3a,0x27,0x5e,0x96 }, - { 0x28,0x3c,0x49,0x8b }, { 0x26,0x35,0x44,0x80 }, - { 0x7c,0x42,0x0f,0xe9 }, { 0x72,0x4b,0x02,0xe2 }, - { 0x60,0x50,0x15,0xff }, { 0x6e,0x59,0x18,0xf4 }, - { 0x44,0x66,0x3b,0xc5 }, { 0x4a,0x6f,0x36,0xce }, - { 0x58,0x74,0x21,0xd3 }, { 0x56,0x7d,0x2c,0xd8 }, - { 0x37,0xa1,0x0c,0x7a }, { 0x39,0xa8,0x01,0x71 }, - { 0x2b,0xb3,0x16,0x6c }, { 0x25,0xba,0x1b,0x67 }, - { 0x0f,0x85,0x38,0x56 }, { 0x01,0x8c,0x35,0x5d }, - { 0x13,0x97,0x22,0x40 }, { 0x1d,0x9e,0x2f,0x4b }, - { 0x47,0xe9,0x64,0x22 }, { 0x49,0xe0,0x69,0x29 }, - { 0x5b,0xfb,0x7e,0x34 }, { 0x55,0xf2,0x73,0x3f }, - { 0x7f,0xcd,0x50,0x0e }, { 0x71,0xc4,0x5d,0x05 }, - { 0x63,0xdf,0x4a,0x18 }, { 0x6d,0xd6,0x47,0x13 }, - { 0xd7,0x31,0xdc,0xca }, { 0xd9,0x38,0xd1,0xc1 }, - { 0xcb,0x23,0xc6,0xdc }, { 0xc5,0x2a,0xcb,0xd7 }, - { 0xef,0x15,0xe8,0xe6 }, { 0xe1,0x1c,0xe5,0xed }, - { 0xf3,0x07,0xf2,0xf0 }, { 0xfd,0x0e,0xff,0xfb }, - { 0xa7,0x79,0xb4,0x92 }, { 0xa9,0x70,0xb9,0x99 }, - { 0xbb,0x6b,0xae,0x84 }, { 0xb5,0x62,0xa3,0x8f }, - { 0x9f,0x5d,0x80,0xbe }, { 0x91,0x54,0x8d,0xb5 }, - { 0x83,0x4f,0x9a,0xa8 }, { 0x8d,0x46,0x97,0xa3 } - }; - -static const unsigned char U2[256][4] = - { - { 0x00,0x00,0x00,0x00 }, { 0x0b,0x0e,0x09,0x0d }, - { 0x16,0x1c,0x12,0x1a }, { 0x1d,0x12,0x1b,0x17 }, - { 0x2c,0x38,0x24,0x34 }, { 0x27,0x36,0x2d,0x39 }, - { 0x3a,0x24,0x36,0x2e }, { 0x31,0x2a,0x3f,0x23 }, - { 0x58,0x70,0x48,0x68 }, { 0x53,0x7e,0x41,0x65 }, - { 0x4e,0x6c,0x5a,0x72 }, { 0x45,0x62,0x53,0x7f }, - { 0x74,0x48,0x6c,0x5c }, { 0x7f,0x46,0x65,0x51 }, - { 0x62,0x54,0x7e,0x46 }, { 0x69,0x5a,0x77,0x4b }, - { 0xb0,0xe0,0x90,0xd0 }, { 0xbb,0xee,0x99,0xdd }, - { 0xa6,0xfc,0x82,0xca }, { 0xad,0xf2,0x8b,0xc7 }, - { 0x9c,0xd8,0xb4,0xe4 }, { 0x97,0xd6,0xbd,0xe9 }, - { 0x8a,0xc4,0xa6,0xfe }, { 0x81,0xca,0xaf,0xf3 }, - { 0xe8,0x90,0xd8,0xb8 }, { 0xe3,0x9e,0xd1,0xb5 }, - { 0xfe,0x8c,0xca,0xa2 }, { 0xf5,0x82,0xc3,0xaf }, - { 0xc4,0xa8,0xfc,0x8c }, { 0xcf,0xa6,0xf5,0x81 }, - { 0xd2,0xb4,0xee,0x96 }, { 0xd9,0xba,0xe7,0x9b }, - { 0x7b,0xdb,0x3b,0xbb }, { 0x70,0xd5,0x32,0xb6 }, - { 0x6d,0xc7,0x29,0xa1 }, { 0x66,0xc9,0x20,0xac }, - { 0x57,0xe3,0x1f,0x8f }, { 0x5c,0xed,0x16,0x82 }, - { 0x41,0xff,0x0d,0x95 }, { 0x4a,0xf1,0x04,0x98 }, - { 0x23,0xab,0x73,0xd3 }, { 0x28,0xa5,0x7a,0xde }, - { 0x35,0xb7,0x61,0xc9 }, { 0x3e,0xb9,0x68,0xc4 }, - { 0x0f,0x93,0x57,0xe7 }, { 0x04,0x9d,0x5e,0xea }, - { 0x19,0x8f,0x45,0xfd }, { 0x12,0x81,0x4c,0xf0 }, - { 0xcb,0x3b,0xab,0x6b }, { 0xc0,0x35,0xa2,0x66 }, - { 0xdd,0x27,0xb9,0x71 }, { 0xd6,0x29,0xb0,0x7c }, - { 0xe7,0x03,0x8f,0x5f }, { 0xec,0x0d,0x86,0x52 }, - { 0xf1,0x1f,0x9d,0x45 }, { 0xfa,0x11,0x94,0x48 }, - { 0x93,0x4b,0xe3,0x03 }, { 0x98,0x45,0xea,0x0e }, - { 0x85,0x57,0xf1,0x19 }, { 0x8e,0x59,0xf8,0x14 }, - { 0xbf,0x73,0xc7,0x37 }, { 0xb4,0x7d,0xce,0x3a }, - { 0xa9,0x6f,0xd5,0x2d }, { 0xa2,0x61,0xdc,0x20 }, - { 0xf6,0xad,0x76,0x6d }, { 0xfd,0xa3,0x7f,0x60 }, - { 0xe0,0xb1,0x64,0x77 }, { 0xeb,0xbf,0x6d,0x7a }, - { 0xda,0x95,0x52,0x59 }, { 0xd1,0x9b,0x5b,0x54 }, - { 0xcc,0x89,0x40,0x43 }, { 0xc7,0x87,0x49,0x4e }, - { 0xae,0xdd,0x3e,0x05 }, { 0xa5,0xd3,0x37,0x08 }, - { 0xb8,0xc1,0x2c,0x1f }, { 0xb3,0xcf,0x25,0x12 }, - { 0x82,0xe5,0x1a,0x31 }, { 0x89,0xeb,0x13,0x3c }, - { 0x94,0xf9,0x08,0x2b }, { 0x9f,0xf7,0x01,0x26 }, - { 0x46,0x4d,0xe6,0xbd }, { 0x4d,0x43,0xef,0xb0 }, - { 0x50,0x51,0xf4,0xa7 }, { 0x5b,0x5f,0xfd,0xaa }, - { 0x6a,0x75,0xc2,0x89 }, { 0x61,0x7b,0xcb,0x84 }, - { 0x7c,0x69,0xd0,0x93 }, { 0x77,0x67,0xd9,0x9e }, - { 0x1e,0x3d,0xae,0xd5 }, { 0x15,0x33,0xa7,0xd8 }, - { 0x08,0x21,0xbc,0xcf }, { 0x03,0x2f,0xb5,0xc2 }, - { 0x32,0x05,0x8a,0xe1 }, { 0x39,0x0b,0x83,0xec }, - { 0x24,0x19,0x98,0xfb }, { 0x2f,0x17,0x91,0xf6 }, - { 0x8d,0x76,0x4d,0xd6 }, { 0x86,0x78,0x44,0xdb }, - { 0x9b,0x6a,0x5f,0xcc }, { 0x90,0x64,0x56,0xc1 }, - { 0xa1,0x4e,0x69,0xe2 }, { 0xaa,0x40,0x60,0xef }, - { 0xb7,0x52,0x7b,0xf8 }, { 0xbc,0x5c,0x72,0xf5 }, - { 0xd5,0x06,0x05,0xbe }, { 0xde,0x08,0x0c,0xb3 }, - { 0xc3,0x1a,0x17,0xa4 }, { 0xc8,0x14,0x1e,0xa9 }, - { 0xf9,0x3e,0x21,0x8a }, { 0xf2,0x30,0x28,0x87 }, - { 0xef,0x22,0x33,0x90 }, { 0xe4,0x2c,0x3a,0x9d }, - { 0x3d,0x96,0xdd,0x06 }, { 0x36,0x98,0xd4,0x0b }, - { 0x2b,0x8a,0xcf,0x1c }, { 0x20,0x84,0xc6,0x11 }, - { 0x11,0xae,0xf9,0x32 }, { 0x1a,0xa0,0xf0,0x3f }, - { 0x07,0xb2,0xeb,0x28 }, { 0x0c,0xbc,0xe2,0x25 }, - { 0x65,0xe6,0x95,0x6e }, { 0x6e,0xe8,0x9c,0x63 }, - { 0x73,0xfa,0x87,0x74 }, { 0x78,0xf4,0x8e,0x79 }, - { 0x49,0xde,0xb1,0x5a }, { 0x42,0xd0,0xb8,0x57 }, - { 0x5f,0xc2,0xa3,0x40 }, { 0x54,0xcc,0xaa,0x4d }, - { 0xf7,0x41,0xec,0xda }, { 0xfc,0x4f,0xe5,0xd7 }, - { 0xe1,0x5d,0xfe,0xc0 }, { 0xea,0x53,0xf7,0xcd }, - { 0xdb,0x79,0xc8,0xee }, { 0xd0,0x77,0xc1,0xe3 }, - { 0xcd,0x65,0xda,0xf4 }, { 0xc6,0x6b,0xd3,0xf9 }, - { 0xaf,0x31,0xa4,0xb2 }, { 0xa4,0x3f,0xad,0xbf }, - { 0xb9,0x2d,0xb6,0xa8 }, { 0xb2,0x23,0xbf,0xa5 }, - { 0x83,0x09,0x80,0x86 }, { 0x88,0x07,0x89,0x8b }, - { 0x95,0x15,0x92,0x9c }, { 0x9e,0x1b,0x9b,0x91 }, - { 0x47,0xa1,0x7c,0x0a }, { 0x4c,0xaf,0x75,0x07 }, - { 0x51,0xbd,0x6e,0x10 }, { 0x5a,0xb3,0x67,0x1d }, - { 0x6b,0x99,0x58,0x3e }, { 0x60,0x97,0x51,0x33 }, - { 0x7d,0x85,0x4a,0x24 }, { 0x76,0x8b,0x43,0x29 }, - { 0x1f,0xd1,0x34,0x62 }, { 0x14,0xdf,0x3d,0x6f }, - { 0x09,0xcd,0x26,0x78 }, { 0x02,0xc3,0x2f,0x75 }, - { 0x33,0xe9,0x10,0x56 }, { 0x38,0xe7,0x19,0x5b }, - { 0x25,0xf5,0x02,0x4c }, { 0x2e,0xfb,0x0b,0x41 }, - { 0x8c,0x9a,0xd7,0x61 }, { 0x87,0x94,0xde,0x6c }, - { 0x9a,0x86,0xc5,0x7b }, { 0x91,0x88,0xcc,0x76 }, - { 0xa0,0xa2,0xf3,0x55 }, { 0xab,0xac,0xfa,0x58 }, - { 0xb6,0xbe,0xe1,0x4f }, { 0xbd,0xb0,0xe8,0x42 }, - { 0xd4,0xea,0x9f,0x09 }, { 0xdf,0xe4,0x96,0x04 }, - { 0xc2,0xf6,0x8d,0x13 }, { 0xc9,0xf8,0x84,0x1e }, - { 0xf8,0xd2,0xbb,0x3d }, { 0xf3,0xdc,0xb2,0x30 }, - { 0xee,0xce,0xa9,0x27 }, { 0xe5,0xc0,0xa0,0x2a }, - { 0x3c,0x7a,0x47,0xb1 }, { 0x37,0x74,0x4e,0xbc }, - { 0x2a,0x66,0x55,0xab }, { 0x21,0x68,0x5c,0xa6 }, - { 0x10,0x42,0x63,0x85 }, { 0x1b,0x4c,0x6a,0x88 }, - { 0x06,0x5e,0x71,0x9f }, { 0x0d,0x50,0x78,0x92 }, - { 0x64,0x0a,0x0f,0xd9 }, { 0x6f,0x04,0x06,0xd4 }, - { 0x72,0x16,0x1d,0xc3 }, { 0x79,0x18,0x14,0xce }, - { 0x48,0x32,0x2b,0xed }, { 0x43,0x3c,0x22,0xe0 }, - { 0x5e,0x2e,0x39,0xf7 }, { 0x55,0x20,0x30,0xfa }, - { 0x01,0xec,0x9a,0xb7 }, { 0x0a,0xe2,0x93,0xba }, - { 0x17,0xf0,0x88,0xad }, { 0x1c,0xfe,0x81,0xa0 }, - { 0x2d,0xd4,0xbe,0x83 }, { 0x26,0xda,0xb7,0x8e }, - { 0x3b,0xc8,0xac,0x99 }, { 0x30,0xc6,0xa5,0x94 }, - { 0x59,0x9c,0xd2,0xdf }, { 0x52,0x92,0xdb,0xd2 }, - { 0x4f,0x80,0xc0,0xc5 }, { 0x44,0x8e,0xc9,0xc8 }, - { 0x75,0xa4,0xf6,0xeb }, { 0x7e,0xaa,0xff,0xe6 }, - { 0x63,0xb8,0xe4,0xf1 }, { 0x68,0xb6,0xed,0xfc }, - { 0xb1,0x0c,0x0a,0x67 }, { 0xba,0x02,0x03,0x6a }, - { 0xa7,0x10,0x18,0x7d }, { 0xac,0x1e,0x11,0x70 }, - { 0x9d,0x34,0x2e,0x53 }, { 0x96,0x3a,0x27,0x5e }, - { 0x8b,0x28,0x3c,0x49 }, { 0x80,0x26,0x35,0x44 }, - { 0xe9,0x7c,0x42,0x0f }, { 0xe2,0x72,0x4b,0x02 }, - { 0xff,0x60,0x50,0x15 }, { 0xf4,0x6e,0x59,0x18 }, - { 0xc5,0x44,0x66,0x3b }, { 0xce,0x4a,0x6f,0x36 }, - { 0xd3,0x58,0x74,0x21 }, { 0xd8,0x56,0x7d,0x2c }, - { 0x7a,0x37,0xa1,0x0c }, { 0x71,0x39,0xa8,0x01 }, - { 0x6c,0x2b,0xb3,0x16 }, { 0x67,0x25,0xba,0x1b }, - { 0x56,0x0f,0x85,0x38 }, { 0x5d,0x01,0x8c,0x35 }, - { 0x40,0x13,0x97,0x22 }, { 0x4b,0x1d,0x9e,0x2f }, - { 0x22,0x47,0xe9,0x64 }, { 0x29,0x49,0xe0,0x69 }, - { 0x34,0x5b,0xfb,0x7e }, { 0x3f,0x55,0xf2,0x73 }, - { 0x0e,0x7f,0xcd,0x50 }, { 0x05,0x71,0xc4,0x5d }, - { 0x18,0x63,0xdf,0x4a }, { 0x13,0x6d,0xd6,0x47 }, - { 0xca,0xd7,0x31,0xdc }, { 0xc1,0xd9,0x38,0xd1 }, - { 0xdc,0xcb,0x23,0xc6 }, { 0xd7,0xc5,0x2a,0xcb }, - { 0xe6,0xef,0x15,0xe8 }, { 0xed,0xe1,0x1c,0xe5 }, - { 0xf0,0xf3,0x07,0xf2 }, { 0xfb,0xfd,0x0e,0xff }, - { 0x92,0xa7,0x79,0xb4 }, { 0x99,0xa9,0x70,0xb9 }, - { 0x84,0xbb,0x6b,0xae }, { 0x8f,0xb5,0x62,0xa3 }, - { 0xbe,0x9f,0x5d,0x80 }, { 0xb5,0x91,0x54,0x8d }, - { 0xa8,0x83,0x4f,0x9a }, { 0xa3,0x8d,0x46,0x97 } - }; - -static const unsigned char U3[256][4] = - { - { 0x00,0x00,0x00,0x00 }, { 0x0d,0x0b,0x0e,0x09 }, - { 0x1a,0x16,0x1c,0x12 }, { 0x17,0x1d,0x12,0x1b }, - { 0x34,0x2c,0x38,0x24 }, { 0x39,0x27,0x36,0x2d }, - { 0x2e,0x3a,0x24,0x36 }, { 0x23,0x31,0x2a,0x3f }, - { 0x68,0x58,0x70,0x48 }, { 0x65,0x53,0x7e,0x41 }, - { 0x72,0x4e,0x6c,0x5a }, { 0x7f,0x45,0x62,0x53 }, - { 0x5c,0x74,0x48,0x6c }, { 0x51,0x7f,0x46,0x65 }, - { 0x46,0x62,0x54,0x7e }, { 0x4b,0x69,0x5a,0x77 }, - { 0xd0,0xb0,0xe0,0x90 }, { 0xdd,0xbb,0xee,0x99 }, - { 0xca,0xa6,0xfc,0x82 }, { 0xc7,0xad,0xf2,0x8b }, - { 0xe4,0x9c,0xd8,0xb4 }, { 0xe9,0x97,0xd6,0xbd }, - { 0xfe,0x8a,0xc4,0xa6 }, { 0xf3,0x81,0xca,0xaf }, - { 0xb8,0xe8,0x90,0xd8 }, { 0xb5,0xe3,0x9e,0xd1 }, - { 0xa2,0xfe,0x8c,0xca }, { 0xaf,0xf5,0x82,0xc3 }, - { 0x8c,0xc4,0xa8,0xfc }, { 0x81,0xcf,0xa6,0xf5 }, - { 0x96,0xd2,0xb4,0xee }, { 0x9b,0xd9,0xba,0xe7 }, - { 0xbb,0x7b,0xdb,0x3b }, { 0xb6,0x70,0xd5,0x32 }, - { 0xa1,0x6d,0xc7,0x29 }, { 0xac,0x66,0xc9,0x20 }, - { 0x8f,0x57,0xe3,0x1f }, { 0x82,0x5c,0xed,0x16 }, - { 0x95,0x41,0xff,0x0d }, { 0x98,0x4a,0xf1,0x04 }, - { 0xd3,0x23,0xab,0x73 }, { 0xde,0x28,0xa5,0x7a }, - { 0xc9,0x35,0xb7,0x61 }, { 0xc4,0x3e,0xb9,0x68 }, - { 0xe7,0x0f,0x93,0x57 }, { 0xea,0x04,0x9d,0x5e }, - { 0xfd,0x19,0x8f,0x45 }, { 0xf0,0x12,0x81,0x4c }, - { 0x6b,0xcb,0x3b,0xab }, { 0x66,0xc0,0x35,0xa2 }, - { 0x71,0xdd,0x27,0xb9 }, { 0x7c,0xd6,0x29,0xb0 }, - { 0x5f,0xe7,0x03,0x8f }, { 0x52,0xec,0x0d,0x86 }, - { 0x45,0xf1,0x1f,0x9d }, { 0x48,0xfa,0x11,0x94 }, - { 0x03,0x93,0x4b,0xe3 }, { 0x0e,0x98,0x45,0xea }, - { 0x19,0x85,0x57,0xf1 }, { 0x14,0x8e,0x59,0xf8 }, - { 0x37,0xbf,0x73,0xc7 }, { 0x3a,0xb4,0x7d,0xce }, - { 0x2d,0xa9,0x6f,0xd5 }, { 0x20,0xa2,0x61,0xdc }, - { 0x6d,0xf6,0xad,0x76 }, { 0x60,0xfd,0xa3,0x7f }, - { 0x77,0xe0,0xb1,0x64 }, { 0x7a,0xeb,0xbf,0x6d }, - { 0x59,0xda,0x95,0x52 }, { 0x54,0xd1,0x9b,0x5b }, - { 0x43,0xcc,0x89,0x40 }, { 0x4e,0xc7,0x87,0x49 }, - { 0x05,0xae,0xdd,0x3e }, { 0x08,0xa5,0xd3,0x37 }, - { 0x1f,0xb8,0xc1,0x2c }, { 0x12,0xb3,0xcf,0x25 }, - { 0x31,0x82,0xe5,0x1a }, { 0x3c,0x89,0xeb,0x13 }, - { 0x2b,0x94,0xf9,0x08 }, { 0x26,0x9f,0xf7,0x01 }, - { 0xbd,0x46,0x4d,0xe6 }, { 0xb0,0x4d,0x43,0xef }, - { 0xa7,0x50,0x51,0xf4 }, { 0xaa,0x5b,0x5f,0xfd }, - { 0x89,0x6a,0x75,0xc2 }, { 0x84,0x61,0x7b,0xcb }, - { 0x93,0x7c,0x69,0xd0 }, { 0x9e,0x77,0x67,0xd9 }, - { 0xd5,0x1e,0x3d,0xae }, { 0xd8,0x15,0x33,0xa7 }, - { 0xcf,0x08,0x21,0xbc }, { 0xc2,0x03,0x2f,0xb5 }, - { 0xe1,0x32,0x05,0x8a }, { 0xec,0x39,0x0b,0x83 }, - { 0xfb,0x24,0x19,0x98 }, { 0xf6,0x2f,0x17,0x91 }, - { 0xd6,0x8d,0x76,0x4d }, { 0xdb,0x86,0x78,0x44 }, - { 0xcc,0x9b,0x6a,0x5f }, { 0xc1,0x90,0x64,0x56 }, - { 0xe2,0xa1,0x4e,0x69 }, { 0xef,0xaa,0x40,0x60 }, - { 0xf8,0xb7,0x52,0x7b }, { 0xf5,0xbc,0x5c,0x72 }, - { 0xbe,0xd5,0x06,0x05 }, { 0xb3,0xde,0x08,0x0c }, - { 0xa4,0xc3,0x1a,0x17 }, { 0xa9,0xc8,0x14,0x1e }, - { 0x8a,0xf9,0x3e,0x21 }, { 0x87,0xf2,0x30,0x28 }, - { 0x90,0xef,0x22,0x33 }, { 0x9d,0xe4,0x2c,0x3a }, - { 0x06,0x3d,0x96,0xdd }, { 0x0b,0x36,0x98,0xd4 }, - { 0x1c,0x2b,0x8a,0xcf }, { 0x11,0x20,0x84,0xc6 }, - { 0x32,0x11,0xae,0xf9 }, { 0x3f,0x1a,0xa0,0xf0 }, - { 0x28,0x07,0xb2,0xeb }, { 0x25,0x0c,0xbc,0xe2 }, - { 0x6e,0x65,0xe6,0x95 }, { 0x63,0x6e,0xe8,0x9c }, - { 0x74,0x73,0xfa,0x87 }, { 0x79,0x78,0xf4,0x8e }, - { 0x5a,0x49,0xde,0xb1 }, { 0x57,0x42,0xd0,0xb8 }, - { 0x40,0x5f,0xc2,0xa3 }, { 0x4d,0x54,0xcc,0xaa }, - { 0xda,0xf7,0x41,0xec }, { 0xd7,0xfc,0x4f,0xe5 }, - { 0xc0,0xe1,0x5d,0xfe }, { 0xcd,0xea,0x53,0xf7 }, - { 0xee,0xdb,0x79,0xc8 }, { 0xe3,0xd0,0x77,0xc1 }, - { 0xf4,0xcd,0x65,0xda }, { 0xf9,0xc6,0x6b,0xd3 }, - { 0xb2,0xaf,0x31,0xa4 }, { 0xbf,0xa4,0x3f,0xad }, - { 0xa8,0xb9,0x2d,0xb6 }, { 0xa5,0xb2,0x23,0xbf }, - { 0x86,0x83,0x09,0x80 }, { 0x8b,0x88,0x07,0x89 }, - { 0x9c,0x95,0x15,0x92 }, { 0x91,0x9e,0x1b,0x9b }, - { 0x0a,0x47,0xa1,0x7c }, { 0x07,0x4c,0xaf,0x75 }, - { 0x10,0x51,0xbd,0x6e }, { 0x1d,0x5a,0xb3,0x67 }, - { 0x3e,0x6b,0x99,0x58 }, { 0x33,0x60,0x97,0x51 }, - { 0x24,0x7d,0x85,0x4a }, { 0x29,0x76,0x8b,0x43 }, - { 0x62,0x1f,0xd1,0x34 }, { 0x6f,0x14,0xdf,0x3d }, - { 0x78,0x09,0xcd,0x26 }, { 0x75,0x02,0xc3,0x2f }, - { 0x56,0x33,0xe9,0x10 }, { 0x5b,0x38,0xe7,0x19 }, - { 0x4c,0x25,0xf5,0x02 }, { 0x41,0x2e,0xfb,0x0b }, - { 0x61,0x8c,0x9a,0xd7 }, { 0x6c,0x87,0x94,0xde }, - { 0x7b,0x9a,0x86,0xc5 }, { 0x76,0x91,0x88,0xcc }, - { 0x55,0xa0,0xa2,0xf3 }, { 0x58,0xab,0xac,0xfa }, - { 0x4f,0xb6,0xbe,0xe1 }, { 0x42,0xbd,0xb0,0xe8 }, - { 0x09,0xd4,0xea,0x9f }, { 0x04,0xdf,0xe4,0x96 }, - { 0x13,0xc2,0xf6,0x8d }, { 0x1e,0xc9,0xf8,0x84 }, - { 0x3d,0xf8,0xd2,0xbb }, { 0x30,0xf3,0xdc,0xb2 }, - { 0x27,0xee,0xce,0xa9 }, { 0x2a,0xe5,0xc0,0xa0 }, - { 0xb1,0x3c,0x7a,0x47 }, { 0xbc,0x37,0x74,0x4e }, - { 0xab,0x2a,0x66,0x55 }, { 0xa6,0x21,0x68,0x5c }, - { 0x85,0x10,0x42,0x63 }, { 0x88,0x1b,0x4c,0x6a }, - { 0x9f,0x06,0x5e,0x71 }, { 0x92,0x0d,0x50,0x78 }, - { 0xd9,0x64,0x0a,0x0f }, { 0xd4,0x6f,0x04,0x06 }, - { 0xc3,0x72,0x16,0x1d }, { 0xce,0x79,0x18,0x14 }, - { 0xed,0x48,0x32,0x2b }, { 0xe0,0x43,0x3c,0x22 }, - { 0xf7,0x5e,0x2e,0x39 }, { 0xfa,0x55,0x20,0x30 }, - { 0xb7,0x01,0xec,0x9a }, { 0xba,0x0a,0xe2,0x93 }, - { 0xad,0x17,0xf0,0x88 }, { 0xa0,0x1c,0xfe,0x81 }, - { 0x83,0x2d,0xd4,0xbe }, { 0x8e,0x26,0xda,0xb7 }, - { 0x99,0x3b,0xc8,0xac }, { 0x94,0x30,0xc6,0xa5 }, - { 0xdf,0x59,0x9c,0xd2 }, { 0xd2,0x52,0x92,0xdb }, - { 0xc5,0x4f,0x80,0xc0 }, { 0xc8,0x44,0x8e,0xc9 }, - { 0xeb,0x75,0xa4,0xf6 }, { 0xe6,0x7e,0xaa,0xff }, - { 0xf1,0x63,0xb8,0xe4 }, { 0xfc,0x68,0xb6,0xed }, - { 0x67,0xb1,0x0c,0x0a }, { 0x6a,0xba,0x02,0x03 }, - { 0x7d,0xa7,0x10,0x18 }, { 0x70,0xac,0x1e,0x11 }, - { 0x53,0x9d,0x34,0x2e }, { 0x5e,0x96,0x3a,0x27 }, - { 0x49,0x8b,0x28,0x3c }, { 0x44,0x80,0x26,0x35 }, - { 0x0f,0xe9,0x7c,0x42 }, { 0x02,0xe2,0x72,0x4b }, - { 0x15,0xff,0x60,0x50 }, { 0x18,0xf4,0x6e,0x59 }, - { 0x3b,0xc5,0x44,0x66 }, { 0x36,0xce,0x4a,0x6f }, - { 0x21,0xd3,0x58,0x74 }, { 0x2c,0xd8,0x56,0x7d }, - { 0x0c,0x7a,0x37,0xa1 }, { 0x01,0x71,0x39,0xa8 }, - { 0x16,0x6c,0x2b,0xb3 }, { 0x1b,0x67,0x25,0xba }, - { 0x38,0x56,0x0f,0x85 }, { 0x35,0x5d,0x01,0x8c }, - { 0x22,0x40,0x13,0x97 }, { 0x2f,0x4b,0x1d,0x9e }, - { 0x64,0x22,0x47,0xe9 }, { 0x69,0x29,0x49,0xe0 }, - { 0x7e,0x34,0x5b,0xfb }, { 0x73,0x3f,0x55,0xf2 }, - { 0x50,0x0e,0x7f,0xcd }, { 0x5d,0x05,0x71,0xc4 }, - { 0x4a,0x18,0x63,0xdf }, { 0x47,0x13,0x6d,0xd6 }, - { 0xdc,0xca,0xd7,0x31 }, { 0xd1,0xc1,0xd9,0x38 }, - { 0xc6,0xdc,0xcb,0x23 }, { 0xcb,0xd7,0xc5,0x2a }, - { 0xe8,0xe6,0xef,0x15 }, { 0xe5,0xed,0xe1,0x1c }, - { 0xf2,0xf0,0xf3,0x07 }, { 0xff,0xfb,0xfd,0x0e }, - { 0xb4,0x92,0xa7,0x79 }, { 0xb9,0x99,0xa9,0x70 }, - { 0xae,0x84,0xbb,0x6b }, { 0xa3,0x8f,0xb5,0x62 }, - { 0x80,0xbe,0x9f,0x5d }, { 0x8d,0xb5,0x91,0x54 }, - { 0x9a,0xa8,0x83,0x4f }, { 0x97,0xa3,0x8d,0x46 } - }; - -static const unsigned char U4[256][4] = +static const u32 decT[256][2] = { - { 0x00,0x00,0x00,0x00 }, { 0x09,0x0d,0x0b,0x0e }, - { 0x12,0x1a,0x16,0x1c }, { 0x1b,0x17,0x1d,0x12 }, - { 0x24,0x34,0x2c,0x38 }, { 0x2d,0x39,0x27,0x36 }, - { 0x36,0x2e,0x3a,0x24 }, { 0x3f,0x23,0x31,0x2a }, - { 0x48,0x68,0x58,0x70 }, { 0x41,0x65,0x53,0x7e }, - { 0x5a,0x72,0x4e,0x6c }, { 0x53,0x7f,0x45,0x62 }, - { 0x6c,0x5c,0x74,0x48 }, { 0x65,0x51,0x7f,0x46 }, - { 0x7e,0x46,0x62,0x54 }, { 0x77,0x4b,0x69,0x5a }, - { 0x90,0xd0,0xb0,0xe0 }, { 0x99,0xdd,0xbb,0xee }, - { 0x82,0xca,0xa6,0xfc }, { 0x8b,0xc7,0xad,0xf2 }, - { 0xb4,0xe4,0x9c,0xd8 }, { 0xbd,0xe9,0x97,0xd6 }, - { 0xa6,0xfe,0x8a,0xc4 }, { 0xaf,0xf3,0x81,0xca }, - { 0xd8,0xb8,0xe8,0x90 }, { 0xd1,0xb5,0xe3,0x9e }, - { 0xca,0xa2,0xfe,0x8c }, { 0xc3,0xaf,0xf5,0x82 }, - { 0xfc,0x8c,0xc4,0xa8 }, { 0xf5,0x81,0xcf,0xa6 }, - { 0xee,0x96,0xd2,0xb4 }, { 0xe7,0x9b,0xd9,0xba }, - { 0x3b,0xbb,0x7b,0xdb }, { 0x32,0xb6,0x70,0xd5 }, - { 0x29,0xa1,0x6d,0xc7 }, { 0x20,0xac,0x66,0xc9 }, - { 0x1f,0x8f,0x57,0xe3 }, { 0x16,0x82,0x5c,0xed }, - { 0x0d,0x95,0x41,0xff }, { 0x04,0x98,0x4a,0xf1 }, - { 0x73,0xd3,0x23,0xab }, { 0x7a,0xde,0x28,0xa5 }, - { 0x61,0xc9,0x35,0xb7 }, { 0x68,0xc4,0x3e,0xb9 }, - { 0x57,0xe7,0x0f,0x93 }, { 0x5e,0xea,0x04,0x9d }, - { 0x45,0xfd,0x19,0x8f }, { 0x4c,0xf0,0x12,0x81 }, - { 0xab,0x6b,0xcb,0x3b }, { 0xa2,0x66,0xc0,0x35 }, - { 0xb9,0x71,0xdd,0x27 }, { 0xb0,0x7c,0xd6,0x29 }, - { 0x8f,0x5f,0xe7,0x03 }, { 0x86,0x52,0xec,0x0d }, - { 0x9d,0x45,0xf1,0x1f }, { 0x94,0x48,0xfa,0x11 }, - { 0xe3,0x03,0x93,0x4b }, { 0xea,0x0e,0x98,0x45 }, - { 0xf1,0x19,0x85,0x57 }, { 0xf8,0x14,0x8e,0x59 }, - { 0xc7,0x37,0xbf,0x73 }, { 0xce,0x3a,0xb4,0x7d }, - { 0xd5,0x2d,0xa9,0x6f }, { 0xdc,0x20,0xa2,0x61 }, - { 0x76,0x6d,0xf6,0xad }, { 0x7f,0x60,0xfd,0xa3 }, - { 0x64,0x77,0xe0,0xb1 }, { 0x6d,0x7a,0xeb,0xbf }, - { 0x52,0x59,0xda,0x95 }, { 0x5b,0x54,0xd1,0x9b }, - { 0x40,0x43,0xcc,0x89 }, { 0x49,0x4e,0xc7,0x87 }, - { 0x3e,0x05,0xae,0xdd }, { 0x37,0x08,0xa5,0xd3 }, - { 0x2c,0x1f,0xb8,0xc1 }, { 0x25,0x12,0xb3,0xcf }, - { 0x1a,0x31,0x82,0xe5 }, { 0x13,0x3c,0x89,0xeb }, - { 0x08,0x2b,0x94,0xf9 }, { 0x01,0x26,0x9f,0xf7 }, - { 0xe6,0xbd,0x46,0x4d }, { 0xef,0xb0,0x4d,0x43 }, - { 0xf4,0xa7,0x50,0x51 }, { 0xfd,0xaa,0x5b,0x5f }, - { 0xc2,0x89,0x6a,0x75 }, { 0xcb,0x84,0x61,0x7b }, - { 0xd0,0x93,0x7c,0x69 }, { 0xd9,0x9e,0x77,0x67 }, - { 0xae,0xd5,0x1e,0x3d }, { 0xa7,0xd8,0x15,0x33 }, - { 0xbc,0xcf,0x08,0x21 }, { 0xb5,0xc2,0x03,0x2f }, - { 0x8a,0xe1,0x32,0x05 }, { 0x83,0xec,0x39,0x0b }, - { 0x98,0xfb,0x24,0x19 }, { 0x91,0xf6,0x2f,0x17 }, - { 0x4d,0xd6,0x8d,0x76 }, { 0x44,0xdb,0x86,0x78 }, - { 0x5f,0xcc,0x9b,0x6a }, { 0x56,0xc1,0x90,0x64 }, - { 0x69,0xe2,0xa1,0x4e }, { 0x60,0xef,0xaa,0x40 }, - { 0x7b,0xf8,0xb7,0x52 }, { 0x72,0xf5,0xbc,0x5c }, - { 0x05,0xbe,0xd5,0x06 }, { 0x0c,0xb3,0xde,0x08 }, - { 0x17,0xa4,0xc3,0x1a }, { 0x1e,0xa9,0xc8,0x14 }, - { 0x21,0x8a,0xf9,0x3e }, { 0x28,0x87,0xf2,0x30 }, - { 0x33,0x90,0xef,0x22 }, { 0x3a,0x9d,0xe4,0x2c }, - { 0xdd,0x06,0x3d,0x96 }, { 0xd4,0x0b,0x36,0x98 }, - { 0xcf,0x1c,0x2b,0x8a }, { 0xc6,0x11,0x20,0x84 }, - { 0xf9,0x32,0x11,0xae }, { 0xf0,0x3f,0x1a,0xa0 }, - { 0xeb,0x28,0x07,0xb2 }, { 0xe2,0x25,0x0c,0xbc }, - { 0x95,0x6e,0x65,0xe6 }, { 0x9c,0x63,0x6e,0xe8 }, - { 0x87,0x74,0x73,0xfa }, { 0x8e,0x79,0x78,0xf4 }, - { 0xb1,0x5a,0x49,0xde }, { 0xb8,0x57,0x42,0xd0 }, - { 0xa3,0x40,0x5f,0xc2 }, { 0xaa,0x4d,0x54,0xcc }, - { 0xec,0xda,0xf7,0x41 }, { 0xe5,0xd7,0xfc,0x4f }, - { 0xfe,0xc0,0xe1,0x5d }, { 0xf7,0xcd,0xea,0x53 }, - { 0xc8,0xee,0xdb,0x79 }, { 0xc1,0xe3,0xd0,0x77 }, - { 0xda,0xf4,0xcd,0x65 }, { 0xd3,0xf9,0xc6,0x6b }, - { 0xa4,0xb2,0xaf,0x31 }, { 0xad,0xbf,0xa4,0x3f }, - { 0xb6,0xa8,0xb9,0x2d }, { 0xbf,0xa5,0xb2,0x23 }, - { 0x80,0x86,0x83,0x09 }, { 0x89,0x8b,0x88,0x07 }, - { 0x92,0x9c,0x95,0x15 }, { 0x9b,0x91,0x9e,0x1b }, - { 0x7c,0x0a,0x47,0xa1 }, { 0x75,0x07,0x4c,0xaf }, - { 0x6e,0x10,0x51,0xbd }, { 0x67,0x1d,0x5a,0xb3 }, - { 0x58,0x3e,0x6b,0x99 }, { 0x51,0x33,0x60,0x97 }, - { 0x4a,0x24,0x7d,0x85 }, { 0x43,0x29,0x76,0x8b }, - { 0x34,0x62,0x1f,0xd1 }, { 0x3d,0x6f,0x14,0xdf }, - { 0x26,0x78,0x09,0xcd }, { 0x2f,0x75,0x02,0xc3 }, - { 0x10,0x56,0x33,0xe9 }, { 0x19,0x5b,0x38,0xe7 }, - { 0x02,0x4c,0x25,0xf5 }, { 0x0b,0x41,0x2e,0xfb }, - { 0xd7,0x61,0x8c,0x9a }, { 0xde,0x6c,0x87,0x94 }, - { 0xc5,0x7b,0x9a,0x86 }, { 0xcc,0x76,0x91,0x88 }, - { 0xf3,0x55,0xa0,0xa2 }, { 0xfa,0x58,0xab,0xac }, - { 0xe1,0x4f,0xb6,0xbe }, { 0xe8,0x42,0xbd,0xb0 }, - { 0x9f,0x09,0xd4,0xea }, { 0x96,0x04,0xdf,0xe4 }, - { 0x8d,0x13,0xc2,0xf6 }, { 0x84,0x1e,0xc9,0xf8 }, - { 0xbb,0x3d,0xf8,0xd2 }, { 0xb2,0x30,0xf3,0xdc }, - { 0xa9,0x27,0xee,0xce }, { 0xa0,0x2a,0xe5,0xc0 }, - { 0x47,0xb1,0x3c,0x7a }, { 0x4e,0xbc,0x37,0x74 }, - { 0x55,0xab,0x2a,0x66 }, { 0x5c,0xa6,0x21,0x68 }, - { 0x63,0x85,0x10,0x42 }, { 0x6a,0x88,0x1b,0x4c }, - { 0x71,0x9f,0x06,0x5e }, { 0x78,0x92,0x0d,0x50 }, - { 0x0f,0xd9,0x64,0x0a }, { 0x06,0xd4,0x6f,0x04 }, - { 0x1d,0xc3,0x72,0x16 }, { 0x14,0xce,0x79,0x18 }, - { 0x2b,0xed,0x48,0x32 }, { 0x22,0xe0,0x43,0x3c }, - { 0x39,0xf7,0x5e,0x2e }, { 0x30,0xfa,0x55,0x20 }, - { 0x9a,0xb7,0x01,0xec }, { 0x93,0xba,0x0a,0xe2 }, - { 0x88,0xad,0x17,0xf0 }, { 0x81,0xa0,0x1c,0xfe }, - { 0xbe,0x83,0x2d,0xd4 }, { 0xb7,0x8e,0x26,0xda }, - { 0xac,0x99,0x3b,0xc8 }, { 0xa5,0x94,0x30,0xc6 }, - { 0xd2,0xdf,0x59,0x9c }, { 0xdb,0xd2,0x52,0x92 }, - { 0xc0,0xc5,0x4f,0x80 }, { 0xc9,0xc8,0x44,0x8e }, - { 0xf6,0xeb,0x75,0xa4 }, { 0xff,0xe6,0x7e,0xaa }, - { 0xe4,0xf1,0x63,0xb8 }, { 0xed,0xfc,0x68,0xb6 }, - { 0x0a,0x67,0xb1,0x0c }, { 0x03,0x6a,0xba,0x02 }, - { 0x18,0x7d,0xa7,0x10 }, { 0x11,0x70,0xac,0x1e }, - { 0x2e,0x53,0x9d,0x34 }, { 0x27,0x5e,0x96,0x3a }, - { 0x3c,0x49,0x8b,0x28 }, { 0x35,0x44,0x80,0x26 }, - { 0x42,0x0f,0xe9,0x7c }, { 0x4b,0x02,0xe2,0x72 }, - { 0x50,0x15,0xff,0x60 }, { 0x59,0x18,0xf4,0x6e }, - { 0x66,0x3b,0xc5,0x44 }, { 0x6f,0x36,0xce,0x4a }, - { 0x74,0x21,0xd3,0x58 }, { 0x7d,0x2c,0xd8,0x56 }, - { 0xa1,0x0c,0x7a,0x37 }, { 0xa8,0x01,0x71,0x39 }, - { 0xb3,0x16,0x6c,0x2b }, { 0xba,0x1b,0x67,0x25 }, - { 0x85,0x38,0x56,0x0f }, { 0x8c,0x35,0x5d,0x01 }, - { 0x97,0x22,0x40,0x13 }, { 0x9e,0x2f,0x4b,0x1d }, - { 0xe9,0x64,0x22,0x47 }, { 0xe0,0x69,0x29,0x49 }, - { 0xfb,0x7e,0x34,0x5b }, { 0xf2,0x73,0x3f,0x55 }, - { 0xcd,0x50,0x0e,0x7f }, { 0xc4,0x5d,0x05,0x71 }, - { 0xdf,0x4a,0x18,0x63 }, { 0xd6,0x47,0x13,0x6d }, - { 0x31,0xdc,0xca,0xd7 }, { 0x38,0xd1,0xc1,0xd9 }, - { 0x23,0xc6,0xdc,0xcb }, { 0x2a,0xcb,0xd7,0xc5 }, - { 0x15,0xe8,0xe6,0xef }, { 0x1c,0xe5,0xed,0xe1 }, - { 0x07,0xf2,0xf0,0xf3 }, { 0x0e,0xff,0xfb,0xfd }, - { 0x79,0xb4,0x92,0xa7 }, { 0x70,0xb9,0x99,0xa9 }, - { 0x6b,0xae,0x84,0xbb }, { 0x62,0xa3,0x8f,0xb5 }, - { 0x5d,0x80,0xbe,0x9f }, { 0x54,0x8d,0xb5,0x91 }, - { 0x4f,0x9a,0xa8,0x83 }, { 0x46,0x97,0xa3,0x8d } + { 0x50a7f451, 0x00000052 }, { 0x5365417e, 0x00000009 }, + { 0xc3a4171a, 0x0000006a }, { 0x965e273a, 0x000000d5 }, + { 0xcb6bab3b, 0x00000030 }, { 0xf1459d1f, 0x00000036 }, + { 0xab58faac, 0x000000a5 }, { 0x9303e34b, 0x00000038 }, + { 0x55fa3020, 0x000000bf }, { 0xf66d76ad, 0x00000040 }, + { 0x9176cc88, 0x000000a3 }, { 0x254c02f5, 0x0000009e }, + { 0xfcd7e54f, 0x00000081 }, { 0xd7cb2ac5, 0x000000f3 }, + { 0x80443526, 0x000000d7 }, { 0x8fa362b5, 0x000000fb }, + { 0x495ab1de, 0x0000007c }, { 0x671bba25, 0x000000e3 }, + { 0x980eea45, 0x00000039 }, { 0xe1c0fe5d, 0x00000082 }, + { 0x02752fc3, 0x0000009b }, { 0x12f04c81, 0x0000002f }, + { 0xa397468d, 0x000000ff }, { 0xc6f9d36b, 0x00000087 }, + { 0xe75f8f03, 0x00000034 }, { 0x959c9215, 0x0000008e }, + { 0xeb7a6dbf, 0x00000043 }, { 0xda595295, 0x00000044 }, + { 0x2d83bed4, 0x000000c4 }, { 0xd3217458, 0x000000de }, + { 0x2969e049, 0x000000e9 }, { 0x44c8c98e, 0x000000cb }, + { 0x6a89c275, 0x00000054 }, { 0x78798ef4, 0x0000007b }, + { 0x6b3e5899, 0x00000094 }, { 0xdd71b927, 0x00000032 }, + { 0xb64fe1be, 0x000000a6 }, { 0x17ad88f0, 0x000000c2 }, + { 0x66ac20c9, 0x00000023 }, { 0xb43ace7d, 0x0000003d }, + { 0x184adf63, 0x000000ee }, { 0x82311ae5, 0x0000004c }, + { 0x60335197, 0x00000095 }, { 0x457f5362, 0x0000000b }, + { 0xe07764b1, 0x00000042 }, { 0x84ae6bbb, 0x000000fa }, + { 0x1ca081fe, 0x000000c3 }, { 0x942b08f9, 0x0000004e }, + { 0x58684870, 0x00000008 }, { 0x19fd458f, 0x0000002e }, + { 0x876cde94, 0x000000a1 }, { 0xb7f87b52, 0x00000066 }, + { 0x23d373ab, 0x00000028 }, { 0xe2024b72, 0x000000d9 }, + { 0x578f1fe3, 0x00000024 }, { 0x2aab5566, 0x000000b2 }, + { 0x0728ebb2, 0x00000076 }, { 0x03c2b52f, 0x0000005b }, + { 0x9a7bc586, 0x000000a2 }, { 0xa50837d3, 0x00000049 }, + { 0xf2872830, 0x0000006d }, { 0xb2a5bf23, 0x0000008b }, + { 0xba6a0302, 0x000000d1 }, { 0x5c8216ed, 0x00000025 }, + { 0x2b1ccf8a, 0x00000072 }, { 0x92b479a7, 0x000000f8 }, + { 0xf0f207f3, 0x000000f6 }, { 0xa1e2694e, 0x00000064 }, + { 0xcdf4da65, 0x00000086 }, { 0xd5be0506, 0x00000068 }, + { 0x1f6234d1, 0x00000098 }, { 0x8afea6c4, 0x00000016 }, + { 0x9d532e34, 0x000000d4 }, { 0xa055f3a2, 0x000000a4 }, + { 0x32e18a05, 0x0000005c }, { 0x75ebf6a4, 0x000000cc }, + { 0x39ec830b, 0x0000005d }, { 0xaaef6040, 0x00000065 }, + { 0x069f715e, 0x000000b6 }, { 0x51106ebd, 0x00000092 }, + { 0xf98a213e, 0x0000006c }, { 0x3d06dd96, 0x00000070 }, + { 0xae053edd, 0x00000048 }, { 0x46bde64d, 0x00000050 }, + { 0xb58d5491, 0x000000fd }, { 0x055dc471, 0x000000ed }, + { 0x6fd40604, 0x000000b9 }, { 0xff155060, 0x000000da }, + { 0x24fb9819, 0x0000005e }, { 0x97e9bdd6, 0x00000015 }, + { 0xcc434089, 0x00000046 }, { 0x779ed967, 0x00000057 }, + { 0xbd42e8b0, 0x000000a7 }, { 0x888b8907, 0x0000008d }, + { 0x385b19e7, 0x0000009d }, { 0xdbeec879, 0x00000084 }, + { 0x470a7ca1, 0x00000090 }, { 0xe90f427c, 0x000000d8 }, + { 0xc91e84f8, 0x000000ab }, { 0x00000000, 0x00000000 }, + { 0x83868009, 0x0000008c }, { 0x48ed2b32, 0x000000bc }, + { 0xac70111e, 0x000000d3 }, { 0x4e725a6c, 0x0000000a }, + { 0xfbff0efd, 0x000000f7 }, { 0x5638850f, 0x000000e4 }, + { 0x1ed5ae3d, 0x00000058 }, { 0x27392d36, 0x00000005 }, + { 0x64d90f0a, 0x000000b8 }, { 0x21a65c68, 0x000000b3 }, + { 0xd1545b9b, 0x00000045 }, { 0x3a2e3624, 0x00000006 }, + { 0xb1670a0c, 0x000000d0 }, { 0x0fe75793, 0x0000002c }, + { 0xd296eeb4, 0x0000001e }, { 0x9e919b1b, 0x0000008f }, + { 0x4fc5c080, 0x000000ca }, { 0xa220dc61, 0x0000003f }, + { 0x694b775a, 0x0000000f }, { 0x161a121c, 0x00000002 }, + { 0x0aba93e2, 0x000000c1 }, { 0xe52aa0c0, 0x000000af }, + { 0x43e0223c, 0x000000bd }, { 0x1d171b12, 0x00000003 }, + { 0x0b0d090e, 0x00000001 }, { 0xadc78bf2, 0x00000013 }, + { 0xb9a8b62d, 0x0000008a }, { 0xc8a91e14, 0x0000006b }, + { 0x8519f157, 0x0000003a }, { 0x4c0775af, 0x00000091 }, + { 0xbbdd99ee, 0x00000011 }, { 0xfd607fa3, 0x00000041 }, + { 0x9f2601f7, 0x0000004f }, { 0xbcf5725c, 0x00000067 }, + { 0xc53b6644, 0x000000dc }, { 0x347efb5b, 0x000000ea }, + { 0x7629438b, 0x00000097 }, { 0xdcc623cb, 0x000000f2 }, + { 0x68fcedb6, 0x000000cf }, { 0x63f1e4b8, 0x000000ce }, + { 0xcadc31d7, 0x000000f0 }, { 0x10856342, 0x000000b4 }, + { 0x40229713, 0x000000e6 }, { 0x2011c684, 0x00000073 }, + { 0x7d244a85, 0x00000096 }, { 0xf83dbbd2, 0x000000ac }, + { 0x1132f9ae, 0x00000074 }, { 0x6da129c7, 0x00000022 }, + { 0x4b2f9e1d, 0x000000e7 }, { 0xf330b2dc, 0x000000ad }, + { 0xec52860d, 0x00000035 }, { 0xd0e3c177, 0x00000085 }, + { 0x6c16b32b, 0x000000e2 }, { 0x99b970a9, 0x000000f9 }, + { 0xfa489411, 0x00000037 }, { 0x2264e947, 0x000000e8 }, + { 0xc48cfca8, 0x0000001c }, { 0x1a3ff0a0, 0x00000075 }, + { 0xd82c7d56, 0x000000df }, { 0xef903322, 0x0000006e }, + { 0xc74e4987, 0x00000047 }, { 0xc1d138d9, 0x000000f1 }, + { 0xfea2ca8c, 0x0000001a }, { 0x360bd498, 0x00000071 }, + { 0xcf81f5a6, 0x0000001d }, { 0x28de7aa5, 0x00000029 }, + { 0x268eb7da, 0x000000c5 }, { 0xa4bfad3f, 0x00000089 }, + { 0xe49d3a2c, 0x0000006f }, { 0x0d927850, 0x000000b7 }, + { 0x9bcc5f6a, 0x00000062 }, { 0x62467e54, 0x0000000e }, + { 0xc2138df6, 0x000000aa }, { 0xe8b8d890, 0x00000018 }, + { 0x5ef7392e, 0x000000be }, { 0xf5afc382, 0x0000001b }, + { 0xbe805d9f, 0x000000fc }, { 0x7c93d069, 0x00000056 }, + { 0xa92dd56f, 0x0000003e }, { 0xb31225cf, 0x0000004b }, + { 0x3b99acc8, 0x000000c6 }, { 0xa77d1810, 0x000000d2 }, + { 0x6e639ce8, 0x00000079 }, { 0x7bbb3bdb, 0x00000020 }, + { 0x097826cd, 0x0000009a }, { 0xf418596e, 0x000000db }, + { 0x01b79aec, 0x000000c0 }, { 0xa89a4f83, 0x000000fe }, + { 0x656e95e6, 0x00000078 }, { 0x7ee6ffaa, 0x000000cd }, + { 0x08cfbc21, 0x0000005a }, { 0xe6e815ef, 0x000000f4 }, + { 0xd99be7ba, 0x0000001f }, { 0xce366f4a, 0x000000dd }, + { 0xd4099fea, 0x000000a8 }, { 0xd67cb029, 0x00000033 }, + { 0xafb2a431, 0x00000088 }, { 0x31233f2a, 0x00000007 }, + { 0x3094a5c6, 0x000000c7 }, { 0xc066a235, 0x00000031 }, + { 0x37bc4e74, 0x000000b1 }, { 0xa6ca82fc, 0x00000012 }, + { 0xb0d090e0, 0x00000010 }, { 0x15d8a733, 0x00000059 }, + { 0x4a9804f1, 0x00000027 }, { 0xf7daec41, 0x00000080 }, + { 0x0e50cd7f, 0x000000ec }, { 0x2ff69117, 0x0000005f }, + { 0x8dd64d76, 0x00000060 }, { 0x4db0ef43, 0x00000051 }, + { 0x544daacc, 0x0000007f }, { 0xdf0496e4, 0x000000a9 }, + { 0xe3b5d19e, 0x00000019 }, { 0x1b886a4c, 0x000000b5 }, + { 0xb81f2cc1, 0x0000004a }, { 0x7f516546, 0x0000000d }, + { 0x04ea5e9d, 0x0000002d }, { 0x5d358c01, 0x000000e5 }, + { 0x737487fa, 0x0000007a }, { 0x2e410bfb, 0x0000009f }, + { 0x5a1d67b3, 0x00000093 }, { 0x52d2db92, 0x000000c9 }, + { 0x335610e9, 0x0000009c }, { 0x1347d66d, 0x000000ef }, + { 0x8c61d79a, 0x000000a0 }, { 0x7a0ca137, 0x000000e0 }, + { 0x8e14f859, 0x0000003b }, { 0x893c13eb, 0x0000004d }, + { 0xee27a9ce, 0x000000ae }, { 0x35c961b7, 0x0000002a }, + { 0xede51ce1, 0x000000f5 }, { 0x3cb1477a, 0x000000b0 }, + { 0x59dfd29c, 0x000000c8 }, { 0x3f73f255, 0x000000eb }, + { 0x79ce1418, 0x000000bb }, { 0xbf37c773, 0x0000003c }, + { 0xeacdf753, 0x00000083 }, { 0x5baafd5f, 0x00000053 }, + { 0x146f3ddf, 0x00000099 }, { 0x86db4478, 0x00000061 }, + { 0x81f3afca, 0x00000017 }, { 0x3ec468b9, 0x0000002b }, + { 0x2c342438, 0x00000004 }, { 0x5f40a3c2, 0x0000007e }, + { 0x72c31d16, 0x000000ba }, { 0x0c25e2bc, 0x00000077 }, + { 0x8b493c28, 0x000000d6 }, { 0x41950dff, 0x00000026 }, + { 0x7101a839, 0x000000e1 }, { 0xdeb30c08, 0x00000069 }, + { 0x9ce4b4d8, 0x00000014 }, { 0x90c15664, 0x00000063 }, + { 0x6184cb7b, 0x00000055 }, { 0x70b632d5, 0x00000021 }, + { 0x745c6c48, 0x0000000c }, { 0x4257b8d0, 0x0000007d } }; static const u32 rcon[30] = diff --git a/cipher/rijndael.c b/cipher/rijndael.c index aa1681d..935bf56 100644 --- a/cipher/rijndael.c +++ b/cipher/rijndael.c @@ -63,12 +63,14 @@ typedef u32 u32_a_t; extern unsigned int _gcry_aes_amd64_encrypt_block(const void *keysched_enc, unsigned char *out, const unsigned char *in, - int rounds); + 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); + int rounds, + const void *decT); #endif /*USE_AMD64_ASM*/ #ifdef USE_AESNI @@ -119,12 +121,14 @@ extern unsigned int _gcry_aes_padlock_decrypt (const RIJNDAEL_context *ctx, extern unsigned int _gcry_aes_arm_encrypt_block(const void *keysched_enc, unsigned char *out, const unsigned char *in, - int rounds); + 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); + int rounds, + const void *decT); #endif /*USE_ARM_ASM*/ static unsigned int do_encrypt (const RIJNDAEL_context *ctx, unsigned char *bx, @@ -145,6 +149,44 @@ static const char *selftest(void); +/* Prefetching for encryption/decryption tables. */ +static void prefetch_table(const volatile byte *tab, size_t len) +{ + size_t i; + + for (i = 0; i < len; i += 16 * 32) + { + (void)tab[i + 0 * 32]; + (void)tab[i + 1 * 32]; + (void)tab[i + 2 * 32]; + (void)tab[i + 3 * 32]; + (void)tab[i + 4 * 32]; + (void)tab[i + 5 * 32]; + (void)tab[i + 6 * 32]; + (void)tab[i + 7 * 32]; + (void)tab[i + 8 * 32]; + (void)tab[i + 9 * 32]; + (void)tab[i + 10 * 32]; + (void)tab[i + 11 * 32]; + (void)tab[i + 12 * 32]; + (void)tab[i + 13 * 32]; + (void)tab[i + 14 * 32]; + (void)tab[i + 15 * 32]; + } +} + +static void prefetch_enc(void) +{ + prefetch_table((const void *)encT, sizeof(encT)); +} + +static void prefetch_dec(void) +{ + prefetch_table((const void *)decT, sizeof(decT)); +} + + + /* Perform the key setup. */ static gcry_err_code_t do_setkey (RIJNDAEL_context *ctx, const byte *key, const unsigned keylen) @@ -216,6 +258,8 @@ do_setkey (RIJNDAEL_context *ctx, const byte *key, const unsigned keylen) { ctx->encrypt_fn = _gcry_aes_aesni_encrypt; ctx->decrypt_fn = _gcry_aes_aesni_decrypt; + ctx->prefetch_enc_fn = NULL; + ctx->prefetch_dec_fn = NULL; ctx->use_aesni = 1; } #endif @@ -224,6 +268,8 @@ do_setkey (RIJNDAEL_context *ctx, const byte *key, const unsigned keylen) { ctx->encrypt_fn = _gcry_aes_padlock_encrypt; ctx->decrypt_fn = _gcry_aes_padlock_decrypt; + ctx->prefetch_enc_fn = NULL; + ctx->prefetch_dec_fn = NULL; ctx->use_padlock = 1; memcpy (ctx->padlockkey, key, keylen); } @@ -232,6 +278,8 @@ do_setkey (RIJNDAEL_context *ctx, const byte *key, const unsigned keylen) { ctx->encrypt_fn = do_encrypt; ctx->decrypt_fn = do_decrypt; + ctx->prefetch_enc_fn = prefetch_enc; + ctx->prefetch_dec_fn = prefetch_dec; } /* NB: We don't yet support Padlock hardware key generation. */ @@ -250,10 +298,13 @@ do_setkey (RIJNDAEL_context *ctx, const byte *key, const unsigned keylen) { PROPERLY_ALIGNED_TYPE dummy; byte data[MAXKC][4]; - } k, tk; -#define k k.data -#define tk tk.data + } tkk[2]; +#define k tkk[0].data +#define tk tkk[1].data #define W (ctx->keyschenc) + + prefetch_enc(); + for (i = 0; i < keylen; i++) { k[i >> 2][i & 3] = key[i]; @@ -270,7 +321,7 @@ do_setkey (RIJNDAEL_context *ctx, const byte *key, const unsigned keylen) { for (; (j < KC) && (t < 4); j++, t++) { - *((u32_a_t*)W[r][t]) = *((u32_a_t*)tk[j]); + *((u32_a_t*)W[r][t]) = le_bswap32(*((u32_a_t*)tk[j])); } if (t == 4) { @@ -283,10 +334,10 @@ do_setkey (RIJNDAEL_context *ctx, const byte *key, const unsigned keylen) { /* While not enough round key material calculated calculate new values. */ - tk[0][0] ^= S[tk[KC-1][1]]; - tk[0][1] ^= S[tk[KC-1][2]]; - tk[0][2] ^= S[tk[KC-1][3]]; - tk[0][3] ^= S[tk[KC-1][0]]; + tk[0][0] ^= encT[tk[KC-1][1]][1]; + tk[0][1] ^= encT[tk[KC-1][2]][1]; + tk[0][2] ^= encT[tk[KC-1][3]][1]; + tk[0][3] ^= encT[tk[KC-1][0]][1]; tk[0][0] ^= rcon[rconpointer++]; if (KC != 8) @@ -302,10 +353,10 @@ do_setkey (RIJNDAEL_context *ctx, const byte *key, const unsigned keylen) { *((u32_a_t*)tk[j]) ^= *((u32_a_t*)tk[j-1]); } - tk[KC/2][0] ^= S[tk[KC/2 - 1][0]]; - tk[KC/2][1] ^= S[tk[KC/2 - 1][1]]; - tk[KC/2][2] ^= S[tk[KC/2 - 1][2]]; - tk[KC/2][3] ^= S[tk[KC/2 - 1][3]]; + tk[KC/2][0] ^= encT[tk[KC/2 - 1][0]][1]; + tk[KC/2][1] ^= encT[tk[KC/2 - 1][1]][1]; + tk[KC/2][2] ^= encT[tk[KC/2 - 1][2]][1]; + tk[KC/2][3] ^= encT[tk[KC/2 - 1][3]][1]; for (j = KC/2 + 1; j < KC; j++) { *((u32_a_t*)tk[j]) ^= *((u32_a_t*)tk[j-1]); @@ -317,7 +368,7 @@ do_setkey (RIJNDAEL_context *ctx, const byte *key, const unsigned keylen) { for (; (j < KC) && (t < 4); j++, t++) { - *((u32_a_t*)W[r][t]) = *((u32_a_t*)tk[j]); + *((u32_a_t*)W[r][t]) = le_bswap32(*((u32_a_t*)tk[j])); } if (t == 4) { @@ -329,8 +380,7 @@ do_setkey (RIJNDAEL_context *ctx, const byte *key, const unsigned keylen) #undef W #undef tk #undef k - wipememory(&tk, sizeof(tk)); - wipememory(&t, sizeof(t)); + wipememory(&tkk, sizeof(tkk)); } return 0; @@ -367,136 +417,137 @@ prepare_decryption( RIJNDAEL_context *ctx ) #endif /*USE_PADLOCK*/ else { - union - { - PROPERLY_ALIGNED_TYPE dummy; - byte *w; - } w; -#define w w.w + prefetch_enc(); + prefetch_dec(); + + *((u32_a_t*)ctx->keyschdec[0][0]) = *((u32_a_t*)ctx->keyschenc[0][0]); + *((u32_a_t*)ctx->keyschdec[0][1]) = *((u32_a_t*)ctx->keyschenc[0][1]); + *((u32_a_t*)ctx->keyschdec[0][2]) = *((u32_a_t*)ctx->keyschenc[0][2]); + *((u32_a_t*)ctx->keyschdec[0][3]) = *((u32_a_t*)ctx->keyschenc[0][3]); - for (r=0; r < MAXROUNDS+1; r++ ) - { - *((u32_a_t*)ctx->keyschdec[r][0]) = *((u32_a_t*)ctx->keyschenc[r][0]); - *((u32_a_t*)ctx->keyschdec[r][1]) = *((u32_a_t*)ctx->keyschenc[r][1]); - *((u32_a_t*)ctx->keyschdec[r][2]) = *((u32_a_t*)ctx->keyschenc[r][2]); - *((u32_a_t*)ctx->keyschdec[r][3]) = *((u32_a_t*)ctx->keyschenc[r][3]); - } -#define W (ctx->keyschdec) for (r = 1; r < ctx->rounds; r++) { - w = W[r][0]; - *((u32_a_t*)w) = *((u32_a_t*)U1[w[0]]) ^ *((u32_a_t*)U2[w[1]]) - ^ *((u32_a_t*)U3[w[2]]) ^ *((u32_a_t*)U4[w[3]]); - - w = W[r][1]; - *((u32_a_t*)w) = *((u32_a_t*)U1[w[0]]) ^ *((u32_a_t*)U2[w[1]]) - ^ *((u32_a_t*)U3[w[2]]) ^ *((u32_a_t*)U4[w[3]]); - - w = W[r][2]; - *((u32_a_t*)w) = *((u32_a_t*)U1[w[0]]) ^ *((u32_a_t*)U2[w[1]]) - ^ *((u32_a_t*)U3[w[2]]) ^ *((u32_a_t*)U4[w[3]]); - - w = W[r][3]; - *((u32_a_t*)w) = *((u32_a_t*)U1[w[0]]) ^ *((u32_a_t*)U2[w[1]]) - ^ *((u32_a_t*)U3[w[2]]) ^ *((u32_a_t*)U4[w[3]]); + u32_a_t *wi = (u32_a_t*)((ctx->keyschenc)[r]); + u32_a_t *wo = (u32_a_t*)((ctx->keyschdec)[r]); + u32 wt; + + wt = wi[0]; + wo[0] = rol(decT[encT[(byte)(wt >> 0)][1]][0], 8 * 0) + ^ rol(decT[encT[(byte)(wt >> 8)][1]][0], 8 * 1) + ^ rol(decT[encT[(byte)(wt >> 16)][1]][0], 8 * 2) + ^ rol(decT[encT[(byte)(wt >> 24)][1]][0], 8 * 3); + + wt = wi[1]; + wo[1] = rol(decT[encT[(byte)(wt >> 0)][1]][0], 8 * 0) + ^ rol(decT[encT[(byte)(wt >> 8)][1]][0], 8 * 1) + ^ rol(decT[encT[(byte)(wt >> 16)][1]][0], 8 * 2) + ^ rol(decT[encT[(byte)(wt >> 24)][1]][0], 8 * 3); + + wt = wi[2]; + wo[2] = rol(decT[encT[(byte)(wt >> 0)][1]][0], 8 * 0) + ^ rol(decT[encT[(byte)(wt >> 8)][1]][0], 8 * 1) + ^ rol(decT[encT[(byte)(wt >> 16)][1]][0], 8 * 2) + ^ rol(decT[encT[(byte)(wt >> 24)][1]][0], 8 * 3); + + wt = wi[3]; + wo[3] = rol(decT[encT[(byte)(wt >> 0)][1]][0], 8 * 0) + ^ rol(decT[encT[(byte)(wt >> 8)][1]][0], 8 * 1) + ^ rol(decT[encT[(byte)(wt >> 16)][1]][0], 8 * 2) + ^ rol(decT[encT[(byte)(wt >> 24)][1]][0], 8 * 3); } -#undef W -#undef w - wipememory(&w, sizeof(w)); + + *((u32_a_t*)ctx->keyschdec[r][0]) = *((u32_a_t*)ctx->keyschenc[r][0]); + *((u32_a_t*)ctx->keyschdec[r][1]) = *((u32_a_t*)ctx->keyschenc[r][1]); + *((u32_a_t*)ctx->keyschdec[r][2]) = *((u32_a_t*)ctx->keyschenc[r][2]); + *((u32_a_t*)ctx->keyschdec[r][3]) = *((u32_a_t*)ctx->keyschenc[r][3]); } } -#if !defined(USE_AMD64_ASM) && !defined(USE_ARM_ASM) -/* Encrypt one block. A and B need to be aligned on a 4 byte - boundary. A and B may be the same. */ -static void -do_encrypt_aligned (const RIJNDAEL_context *ctx, - unsigned char *b, const unsigned char *a) +#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->keyschenc) int rounds = ctx->rounds; int r; - union - { - u32 tempu32[4]; /* Force correct alignment. */ - byte temp[4][4]; - } u; - - *((u32_a_t*)u.temp[0]) = *((u32_a_t*)(a )) ^ *((u32_a_t*)rk[0][0]); - *((u32_a_t*)u.temp[1]) = *((u32_a_t*)(a+ 4)) ^ *((u32_a_t*)rk[0][1]); - *((u32_a_t*)u.temp[2]) = *((u32_a_t*)(a+ 8)) ^ *((u32_a_t*)rk[0][2]); - *((u32_a_t*)u.temp[3]) = *((u32_a_t*)(a+12)) ^ *((u32_a_t*)rk[0][3]); - *((u32_a_t*)(b )) = (*((u32_a_t*)T1[u.temp[0][0]]) - ^ *((u32_a_t*)T2[u.temp[1][1]]) - ^ *((u32_a_t*)T3[u.temp[2][2]]) - ^ *((u32_a_t*)T4[u.temp[3][3]])); - *((u32_a_t*)(b + 4)) = (*((u32_a_t*)T1[u.temp[1][0]]) - ^ *((u32_a_t*)T2[u.temp[2][1]]) - ^ *((u32_a_t*)T3[u.temp[3][2]]) - ^ *((u32_a_t*)T4[u.temp[0][3]])); - *((u32_a_t*)(b + 8)) = (*((u32_a_t*)T1[u.temp[2][0]]) - ^ *((u32_a_t*)T2[u.temp[3][1]]) - ^ *((u32_a_t*)T3[u.temp[0][2]]) - ^ *((u32_a_t*)T4[u.temp[1][3]])); - *((u32_a_t*)(b +12)) = (*((u32_a_t*)T1[u.temp[3][0]]) - ^ *((u32_a_t*)T2[u.temp[0][1]]) - ^ *((u32_a_t*)T3[u.temp[1][2]]) - ^ *((u32_a_t*)T4[u.temp[2][3]])); - - for (r = 1; r < rounds-1; 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] ^ *((u32_a_t*)rk[0][0]); + sa[1] = sb[1] ^ *((u32_a_t*)rk[0][1]); + sa[2] = sb[2] ^ *((u32_a_t*)rk[0][2]); + sa[3] = sb[3] ^ *((u32_a_t*)rk[0][3]); + + for (r = 1; r < rounds; r++) { - *((u32_a_t*)u.temp[0]) = *((u32_a_t*)(b )) ^ *((u32_a_t*)rk[r][0]); - *((u32_a_t*)u.temp[1]) = *((u32_a_t*)(b+ 4)) ^ *((u32_a_t*)rk[r][1]); - *((u32_a_t*)u.temp[2]) = *((u32_a_t*)(b+ 8)) ^ *((u32_a_t*)rk[r][2]); - *((u32_a_t*)u.temp[3]) = *((u32_a_t*)(b+12)) ^ *((u32_a_t*)rk[r][3]); - - *((u32_a_t*)(b )) = (*((u32_a_t*)T1[u.temp[0][0]]) - ^ *((u32_a_t*)T2[u.temp[1][1]]) - ^ *((u32_a_t*)T3[u.temp[2][2]]) - ^ *((u32_a_t*)T4[u.temp[3][3]])); - *((u32_a_t*)(b + 4)) = (*((u32_a_t*)T1[u.temp[1][0]]) - ^ *((u32_a_t*)T2[u.temp[2][1]]) - ^ *((u32_a_t*)T3[u.temp[3][2]]) - ^ *((u32_a_t*)T4[u.temp[0][3]])); - *((u32_a_t*)(b + 8)) = (*((u32_a_t*)T1[u.temp[2][0]]) - ^ *((u32_a_t*)T2[u.temp[3][1]]) - ^ *((u32_a_t*)T3[u.temp[0][2]]) - ^ *((u32_a_t*)T4[u.temp[1][3]])); - *((u32_a_t*)(b +12)) = (*((u32_a_t*)T1[u.temp[3][0]]) - ^ *((u32_a_t*)T2[u.temp[0][1]]) - ^ *((u32_a_t*)T3[u.temp[1][2]]) - ^ *((u32_a_t*)T4[u.temp[2][3]])); + sb[0] = rol(encT[(byte)(sa[0] >> (0 * 8))][0], (0 * 8)); + sb[3] = rol(encT[(byte)(sa[0] >> (1 * 8))][0], (1 * 8)); + sb[2] = rol(encT[(byte)(sa[0] >> (2 * 8))][0], (2 * 8)); + sb[1] = rol(encT[(byte)(sa[0] >> (3 * 8))][0], (3 * 8)); + sa[0] = *((u32_a_t*)rk[r][0]) ^ sb[0]; + + sb[1] ^= rol(encT[(byte)(sa[1] >> (0 * 8))][0], (0 * 8)); + sa[0] ^= rol(encT[(byte)(sa[1] >> (1 * 8))][0], (1 * 8)); + sb[3] ^= rol(encT[(byte)(sa[1] >> (2 * 8))][0], (2 * 8)); + sb[2] ^= rol(encT[(byte)(sa[1] >> (3 * 8))][0], (3 * 8)); + sa[1] = *((u32_a_t*)rk[r][1]) ^ sb[1]; + + sb[2] ^= rol(encT[(byte)(sa[2] >> (0 * 8))][0], (0 * 8)); + sa[1] ^= rol(encT[(byte)(sa[2] >> (1 * 8))][0], (1 * 8)); + sa[0] ^= rol(encT[(byte)(sa[2] >> (2 * 8))][0], (2 * 8)); + sb[3] ^= rol(encT[(byte)(sa[2] >> (3 * 8))][0], (3 * 8)); + sa[2] = *((u32_a_t*)rk[r][2]) ^ sb[2]; + + sb[3] ^= rol(encT[(byte)(sa[3] >> (0 * 8))][0], (0 * 8)); + sa[2] ^= rol(encT[(byte)(sa[3] >> (1 * 8))][0], (1 * 8)); + sa[1] ^= rol(encT[(byte)(sa[3] >> (2 * 8))][0], (2 * 8)); + sa[0] ^= rol(encT[(byte)(sa[3] >> (3 * 8))][0], (3 * 8)); + sa[3] = *((u32_a_t*)rk[r][3]) ^ sb[3]; } /* Last round is special. */ - *((u32_a_t*)u.temp[0]) = *((u32_a_t*)(b )) ^ *((u32_a_t*)rk[rounds-1][0]); - *((u32_a_t*)u.temp[1]) = *((u32_a_t*)(b+ 4)) ^ *((u32_a_t*)rk[rounds-1][1]); - *((u32_a_t*)u.temp[2]) = *((u32_a_t*)(b+ 8)) ^ *((u32_a_t*)rk[rounds-1][2]); - *((u32_a_t*)u.temp[3]) = *((u32_a_t*)(b+12)) ^ *((u32_a_t*)rk[rounds-1][3]); - b[ 0] = T1[u.temp[0][0]][1]; - b[ 1] = T1[u.temp[1][1]][1]; - b[ 2] = T1[u.temp[2][2]][1]; - b[ 3] = T1[u.temp[3][3]][1]; - b[ 4] = T1[u.temp[1][0]][1]; - b[ 5] = T1[u.temp[2][1]][1]; - b[ 6] = T1[u.temp[3][2]][1]; - b[ 7] = T1[u.temp[0][3]][1]; - b[ 8] = T1[u.temp[2][0]][1]; - b[ 9] = T1[u.temp[3][1]][1]; - b[10] = T1[u.temp[0][2]][1]; - b[11] = T1[u.temp[1][3]][1]; - b[12] = T1[u.temp[3][0]][1]; - b[13] = T1[u.temp[0][1]][1]; - b[14] = T1[u.temp[1][2]][1]; - b[15] = T1[u.temp[2][3]][1]; - *((u32_a_t*)(b )) ^= *((u32_a_t*)rk[rounds][0]); - *((u32_a_t*)(b+ 4)) ^= *((u32_a_t*)rk[rounds][1]); - *((u32_a_t*)(b+ 8)) ^= *((u32_a_t*)rk[rounds][2]); - *((u32_a_t*)(b+12)) ^= *((u32_a_t*)rk[rounds][3]); + sb[0] = encT[(byte)(sa[0] >> (0 * 8))][1] << (0 * 8); + sb[1] = encT[(byte)(sa[0] >> (3 * 8))][1] << (3 * 8); + sb[2] = encT[(byte)(sa[0] >> (2 * 8))][1] << (2 * 8); + sb[3] = encT[(byte)(sa[0] >> (1 * 8))][1] << (1 * 8); + + sb[1] |= encT[(byte)(sa[1] >> (0 * 8))][1] << (0 * 8); + sb[2] |= encT[(byte)(sa[1] >> (3 * 8))][1] << (3 * 8); + sb[3] |= encT[(byte)(sa[1] >> (2 * 8))][1] << (2 * 8); + sb[0] |= encT[(byte)(sa[1] >> (1 * 8))][1] << (1 * 8); + + sb[2] |= encT[(byte)(sa[2] >> (0 * 8))][1] << (0 * 8); + sb[3] |= encT[(byte)(sa[2] >> (3 * 8))][1] << (3 * 8); + sb[0] |= encT[(byte)(sa[2] >> (2 * 8))][1] << (2 * 8); + sb[1] |= encT[(byte)(sa[2] >> (1 * 8))][1] << (1 * 8); + + sb[3] |= encT[(byte)(sa[3] >> (0 * 8))][1] << (0 * 8); + sb[0] |= encT[(byte)(sa[3] >> (3 * 8))][1] << (3 * 8); + sb[1] |= encT[(byte)(sa[3] >> (2 * 8))][1] << (2 * 8); + sb[2] |= encT[(byte)(sa[3] >> (1 * 8))][1] << (1 * 8); + + sa[0] = sb[0] ^ *((u32_a_t*)rk[r][0]); + sa[1] = sb[1] ^ *((u32_a_t*)rk[r][1]); + sa[2] = sb[2] ^ *((u32_a_t*)rk[r][2]); + sa[3] = sb[3] ^ *((u32_a_t*)rk[r][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_AMD64_ASM && !USE_ARM_ASM*/ +#endif /*!USE_ARM_ASM && !USE_AMD64_ASM*/ static unsigned int @@ -504,31 +555,13 @@ 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); + return _gcry_aes_amd64_encrypt_block(ctx->keyschenc, bx, ax, ctx->rounds, + encT); #elif defined(USE_ARM_ASM) - return _gcry_aes_arm_encrypt_block(ctx->keyschenc, bx, ax, ctx->rounds); + return _gcry_aes_arm_encrypt_block(ctx->keyschenc, bx, ax, ctx->rounds, encT); #else - /* BX and AX are not necessary correctly aligned. Thus we might - need to copy them here. We try to align to a 16 bytes. */ - if (((size_t)ax & 0x0f) || ((size_t)bx & 0x0f)) - { - union - { - u32 dummy[4]; - byte a[16] ATTR_ALIGNED_16; - } a; - - buf_cpy (a.a, ax, 16); - do_encrypt_aligned (ctx, a.a, a.a); - buf_cpy (bx, a.a, 16); - } - else - { - do_encrypt_aligned (ctx, bx, ax); - } - - return (56 + 2*sizeof(int)); -#endif /*!USE_AMD64_ASM && !USE_ARM_ASM*/ + return do_encrypt_fn (ctx, bx, ax); +#endif /* !USE_ARM_ASM && !USE_AMD64_ASM*/ } @@ -537,6 +570,9 @@ 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); } @@ -555,6 +591,9 @@ _gcry_aes_cfb_enc (void *context, unsigned char *iv, const unsigned char *inbuf = inbuf_arg; unsigned int burn_depth = 0; + if (ctx->prefetch_enc_fn) + ctx->prefetch_enc_fn(); + if (0) ; #ifdef USE_AESNI @@ -599,6 +638,9 @@ _gcry_aes_cbc_enc (void *context, unsigned char *iv, unsigned char *last_iv; unsigned int burn_depth = 0; + if (ctx->prefetch_enc_fn) + ctx->prefetch_enc_fn(); + if (0) ; #ifdef USE_AESNI @@ -651,6 +693,9 @@ _gcry_aes_ctr_enc (void *context, unsigned char *ctr, unsigned int burn_depth = 0; int i; + if (ctx->prefetch_enc_fn) + ctx->prefetch_enc_fn(); + if (0) ; #ifdef USE_AESNI @@ -691,98 +736,90 @@ _gcry_aes_ctr_enc (void *context, unsigned char *ctr, -#if !defined(USE_AMD64_ASM) && !defined(USE_ARM_ASM) -/* Decrypt one block. A and B need to be aligned on a 4 byte boundary - and the decryption must have been prepared. A and B may be the - same. */ -static void -do_decrypt_aligned (const RIJNDAEL_context *ctx, - unsigned char *b, const unsigned char *a) +#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->keyschdec) int rounds = ctx->rounds; int r; - union - { - u32 tempu32[4]; /* Force correct alignment. */ - byte temp[4][4]; - } u; - - - *((u32_a_t*)u.temp[0]) = *((u32_a_t*)(a )) ^ *((u32_a_t*)rk[rounds][0]); - *((u32_a_t*)u.temp[1]) = *((u32_a_t*)(a+ 4)) ^ *((u32_a_t*)rk[rounds][1]); - *((u32_a_t*)u.temp[2]) = *((u32_a_t*)(a+ 8)) ^ *((u32_a_t*)rk[rounds][2]); - *((u32_a_t*)u.temp[3]) = *((u32_a_t*)(a+12)) ^ *((u32_a_t*)rk[rounds][3]); - - *((u32_a_t*)(b )) = (*((u32_a_t*)T5[u.temp[0][0]]) - ^ *((u32_a_t*)T6[u.temp[3][1]]) - ^ *((u32_a_t*)T7[u.temp[2][2]]) - ^ *((u32_a_t*)T8[u.temp[1][3]])); - *((u32_a_t*)(b+ 4)) = (*((u32_a_t*)T5[u.temp[1][0]]) - ^ *((u32_a_t*)T6[u.temp[0][1]]) - ^ *((u32_a_t*)T7[u.temp[3][2]]) - ^ *((u32_a_t*)T8[u.temp[2][3]])); - *((u32_a_t*)(b+ 8)) = (*((u32_a_t*)T5[u.temp[2][0]]) - ^ *((u32_a_t*)T6[u.temp[1][1]]) - ^ *((u32_a_t*)T7[u.temp[0][2]]) - ^ *((u32_a_t*)T8[u.temp[3][3]])); - *((u32_a_t*)(b+12)) = (*((u32_a_t*)T5[u.temp[3][0]]) - ^ *((u32_a_t*)T6[u.temp[2][1]]) - ^ *((u32_a_t*)T7[u.temp[1][2]]) - ^ *((u32_a_t*)T8[u.temp[0][3]])); - - for (r = rounds-1; r > 1; 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] ^ *((u32_a_t*)rk[rounds][0]); + sa[1] = sb[1] ^ *((u32_a_t*)rk[rounds][1]); + sa[2] = sb[2] ^ *((u32_a_t*)rk[rounds][2]); + sa[3] = sb[3] ^ *((u32_a_t*)rk[rounds][3]); + + for (r = rounds - 1; r > 0; r--) { - *((u32_a_t*)u.temp[0]) = *((u32_a_t*)(b )) ^ *((u32_a_t*)rk[r][0]); - *((u32_a_t*)u.temp[1]) = *((u32_a_t*)(b+ 4)) ^ *((u32_a_t*)rk[r][1]); - *((u32_a_t*)u.temp[2]) = *((u32_a_t*)(b+ 8)) ^ *((u32_a_t*)rk[r][2]); - *((u32_a_t*)u.temp[3]) = *((u32_a_t*)(b+12)) ^ *((u32_a_t*)rk[r][3]); - *((u32_a_t*)(b )) = (*((u32_a_t*)T5[u.temp[0][0]]) - ^ *((u32_a_t*)T6[u.temp[3][1]]) - ^ *((u32_a_t*)T7[u.temp[2][2]]) - ^ *((u32_a_t*)T8[u.temp[1][3]])); - *((u32_a_t*)(b+ 4)) = (*((u32_a_t*)T5[u.temp[1][0]]) - ^ *((u32_a_t*)T6[u.temp[0][1]]) - ^ *((u32_a_t*)T7[u.temp[3][2]]) - ^ *((u32_a_t*)T8[u.temp[2][3]])); - *((u32_a_t*)(b+ 8)) = (*((u32_a_t*)T5[u.temp[2][0]]) - ^ *((u32_a_t*)T6[u.temp[1][1]]) - ^ *((u32_a_t*)T7[u.temp[0][2]]) - ^ *((u32_a_t*)T8[u.temp[3][3]])); - *((u32_a_t*)(b+12)) = (*((u32_a_t*)T5[u.temp[3][0]]) - ^ *((u32_a_t*)T6[u.temp[2][1]]) - ^ *((u32_a_t*)T7[u.temp[1][2]]) - ^ *((u32_a_t*)T8[u.temp[0][3]])); + sb[0] = rol(decT[(byte)(sa[0] >> (0 * 8))][0], (0 * 8)); + sb[1] = rol(decT[(byte)(sa[0] >> (1 * 8))][0], (1 * 8)); + sb[2] = rol(decT[(byte)(sa[0] >> (2 * 8))][0], (2 * 8)); + sb[3] = rol(decT[(byte)(sa[0] >> (3 * 8))][0], (3 * 8)); + sa[0] = *((u32_a_t*)rk[r][0]) ^ sb[0]; + + sb[1] ^= rol(decT[(byte)(sa[1] >> (0 * 8))][0], (0 * 8)); + sb[2] ^= rol(decT[(byte)(sa[1] >> (1 * 8))][0], (1 * 8)); + sb[3] ^= rol(decT[(byte)(sa[1] >> (2 * 8))][0], (2 * 8)); + sa[0] ^= rol(decT[(byte)(sa[1] >> (3 * 8))][0], (3 * 8)); + sa[1] = *((u32_a_t*)rk[r][1]) ^ sb[1]; + + sb[2] ^= rol(decT[(byte)(sa[2] >> (0 * 8))][0], (0 * 8)); + sb[3] ^= rol(decT[(byte)(sa[2] >> (1 * 8))][0], (1 * 8)); + sa[0] ^= rol(decT[(byte)(sa[2] >> (2 * 8))][0], (2 * 8)); + sa[1] ^= rol(decT[(byte)(sa[2] >> (3 * 8))][0], (3 * 8)); + sa[2] = *((u32_a_t*)rk[r][2]) ^ sb[2]; + + sb[3] ^= rol(decT[(byte)(sa[3] >> (0 * 8))][0], (0 * 8)); + sa[0] ^= rol(decT[(byte)(sa[3] >> (1 * 8))][0], (1 * 8)); + sa[1] ^= rol(decT[(byte)(sa[3] >> (2 * 8))][0], (2 * 8)); + sa[2] ^= rol(decT[(byte)(sa[3] >> (3 * 8))][0], (3 * 8)); + sa[3] = *((u32_a_t*)rk[r][3]) ^ sb[3]; } /* Last round is special. */ - *((u32_a_t*)u.temp[0]) = *((u32_a_t*)(b )) ^ *((u32_a_t*)rk[1][0]); - *((u32_a_t*)u.temp[1]) = *((u32_a_t*)(b+ 4)) ^ *((u32_a_t*)rk[1][1]); - *((u32_a_t*)u.temp[2]) = *((u32_a_t*)(b+ 8)) ^ *((u32_a_t*)rk[1][2]); - *((u32_a_t*)u.temp[3]) = *((u32_a_t*)(b+12)) ^ *((u32_a_t*)rk[1][3]); - b[ 0] = S5[u.temp[0][0]]; - b[ 1] = S5[u.temp[3][1]]; - b[ 2] = S5[u.temp[2][2]]; - b[ 3] = S5[u.temp[1][3]]; - b[ 4] = S5[u.temp[1][0]]; - b[ 5] = S5[u.temp[0][1]]; - b[ 6] = S5[u.temp[3][2]]; - b[ 7] = S5[u.temp[2][3]]; - b[ 8] = S5[u.temp[2][0]]; - b[ 9] = S5[u.temp[1][1]]; - b[10] = S5[u.temp[0][2]]; - b[11] = S5[u.temp[3][3]]; - b[12] = S5[u.temp[3][0]]; - b[13] = S5[u.temp[2][1]]; - b[14] = S5[u.temp[1][2]]; - b[15] = S5[u.temp[0][3]]; - *((u32_a_t*)(b )) ^= *((u32_a_t*)rk[0][0]); - *((u32_a_t*)(b+ 4)) ^= *((u32_a_t*)rk[0][1]); - *((u32_a_t*)(b+ 8)) ^= *((u32_a_t*)rk[0][2]); - *((u32_a_t*)(b+12)) ^= *((u32_a_t*)rk[0][3]); + sb[0] = decT[(byte)(sa[0] >> (0 * 8))][1] << (0 * 8); + sb[1] = decT[(byte)(sa[0] >> (1 * 8))][1] << (1 * 8); + sb[2] = decT[(byte)(sa[0] >> (2 * 8))][1] << (2 * 8); + sb[3] = decT[(byte)(sa[0] >> (3 * 8))][1] << (3 * 8); + + sb[1] |= decT[(byte)(sa[1] >> (0 * 8))][1] << (0 * 8); + sb[2] |= decT[(byte)(sa[1] >> (1 * 8))][1] << (1 * 8); + sb[3] |= decT[(byte)(sa[1] >> (2 * 8))][1] << (2 * 8); + sb[0] |= decT[(byte)(sa[1] >> (3 * 8))][1] << (3 * 8); + + sb[2] |= decT[(byte)(sa[2] >> (0 * 8))][1] << (0 * 8); + sb[3] |= decT[(byte)(sa[2] >> (1 * 8))][1] << (1 * 8); + sb[0] |= decT[(byte)(sa[2] >> (2 * 8))][1] << (2 * 8); + sb[1] |= decT[(byte)(sa[2] >> (3 * 8))][1] << (3 * 8); + + sb[3] |= decT[(byte)(sa[3] >> (0 * 8))][1] << (0 * 8); + sb[0] |= decT[(byte)(sa[3] >> (1 * 8))][1] << (1 * 8); + sb[1] |= decT[(byte)(sa[3] >> (2 * 8))][1] << (2 * 8); + sb[2] |= decT[(byte)(sa[3] >> (3 * 8))][1] << (3 * 8); + + sa[0] = sb[0] ^ *((u32_a_t*)rk[0][0]); + sa[1] = sb[1] ^ *((u32_a_t*)rk[0][1]); + sa[2] = sb[2] ^ *((u32_a_t*)rk[0][2]); + sa[3] = sb[3] ^ *((u32_a_t*)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_AMD64_ASM && !USE_ARM_ASM*/ +#endif /*!USE_ARM_ASM && !USE_AMD64_ASM*/ /* Decrypt one block. AX and BX may be the same. */ @@ -791,31 +828,13 @@ 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); + return _gcry_aes_amd64_decrypt_block(ctx->keyschdec, bx, ax, ctx->rounds, + decT); #elif defined(USE_ARM_ASM) - return _gcry_aes_arm_decrypt_block(ctx->keyschdec, bx, ax, ctx->rounds); + return _gcry_aes_arm_decrypt_block(ctx->keyschdec, bx, ax, ctx->rounds, decT); #else - /* BX and AX are not necessary correctly aligned. Thus we might - need to copy them here. We try to align to a 16 bytes. */ - if (((size_t)ax & 0x0f) || ((size_t)bx & 0x0f)) - { - union - { - u32 dummy[4]; - byte a[16] ATTR_ALIGNED_16; - } a; - - buf_cpy (a.a, ax, 16); - do_decrypt_aligned (ctx, a.a, a.a); - buf_cpy (bx, a.a, 16); - } - else - { - do_decrypt_aligned (ctx, bx, ax); - } - - return (56+2*sizeof(int)); -#endif /*!USE_AMD64_ASM && !USE_ARM_ASM*/ + return do_decrypt_fn (ctx, bx, ax); +#endif /*!USE_ARM_ASM && !USE_AMD64_ASM*/ } @@ -837,6 +856,9 @@ rijndael_decrypt (void *context, byte *b, const byte *a) check_decryption_preparation (ctx); + if (ctx->prefetch_dec_fn) + ctx->prefetch_dec_fn(); + return ctx->decrypt_fn (ctx, b, a); } @@ -855,6 +877,9 @@ _gcry_aes_cfb_dec (void *context, unsigned char *iv, const unsigned char *inbuf = inbuf_arg; unsigned int burn_depth = 0; + if (ctx->prefetch_enc_fn) + ctx->prefetch_enc_fn(); + if (0) ; #ifdef USE_AESNI @@ -898,6 +923,9 @@ _gcry_aes_cbc_dec (void *context, unsigned char *iv, check_decryption_preparation (ctx); + if (ctx->prefetch_dec_fn) + ctx->prefetch_dec_fn(); + if (0) ; #ifdef USE_AESNI @@ -932,7 +960,6 @@ _gcry_aes_cbc_dec (void *context, unsigned char *iv, } - /* Run the self-tests for AES 128. Returns NULL on success. */ static const char* From cvs at cvs.gnupg.org Mon Dec 15 12:15:43 2014 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Mon, 15 Dec 2014 12:15:43 +0100 Subject: [git] GCRYPT - branch, master, updated. libgcrypt-1.6.0-135-gad50e36 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU crypto library". The branch, master has been updated via ad50e360ef4851e66e51a03fc420175636336b58 (commit) from 4f46374502eb988d701b904f83819e2cf7b1755c (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit ad50e360ef4851e66e51a03fc420175636336b58 Author: Werner Koch Date: Mon Dec 15 12:05:32 2014 +0100 build: Add configure option --disable-doc. * Makefile.am (AUTOMAKE_OPTIONS): Remove. (doc) [!BUILD_DOC]: Do not recurse into the dir. * configure.ac (AM_INIT_AUTOMAKE): Add option formerly in Makefile.am. (BUILD_DOC): Add new am_conditional. diff --git a/Makefile.am b/Makefile.am index 937bdaf..2d7ca43 100644 --- a/Makefile.am +++ b/Makefile.am @@ -18,15 +18,21 @@ # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA ACLOCAL_AMFLAGS = -I m4 -AUTOMAKE_OPTIONS = dist-bzip2 -DISTCHECK_CONFIGURE_FLAGS = --disable-random-daemon \ +DISTCHECK_CONFIGURE_FLAGS = --disable-random-daemon --enable-doc \ --enable-ciphers=arcfour:blowfish:cast5:des:aes:twofish:serpent:rfc2268:seed:camellia # (A suitable gitlog-to-changelog script can be found in GnuPG master.) GITLOG_TO_CHANGELOG=gitlog-to-changelog +if BUILD_DOC +doc = doc +else +doc = +endif + + DIST_SUBDIRS = m4 compat mpi cipher random src doc tests -SUBDIRS = compat mpi cipher random src doc tests +SUBDIRS = compat mpi cipher random src $(doc) tests EXTRA_DIST = autogen.sh autogen.rc README.GIT LICENSES \ ChangeLog-2011 build-aux/ChangeLog-2011 doc/ChangeLog-2011 \ diff --git a/configure.ac b/configure.ac index c979d57..a4ea990 100644 --- a/configure.ac +++ b/configure.ac @@ -75,7 +75,7 @@ VERSION=$PACKAGE_VERSION AC_CONFIG_AUX_DIR([build-aux]) AC_CONFIG_SRCDIR([src/libgcrypt.vers]) -AM_INIT_AUTOMAKE +AM_INIT_AUTOMAKE([dist-bzip2]) AC_CONFIG_HEADER(config.h) AC_CONFIG_MACRO_DIR([m4]) AC_CONFIG_LIBOBJ_DIR([compat]) @@ -2090,6 +2090,16 @@ AC_SUBST([GCRYPT_HWF_MODULES]) # +# Option to disable building of doc file +# +build_doc=yes +AC_ARG_ENABLE([doc], AC_HELP_STRING([--disable-doc], + [do not build the documentation]), + build_doc=$enableval, build_doc=yes) +AM_CONDITIONAL([BUILD_DOC], [test "x$build_doc" != xno]) + + +# # Provide information about the build. # BUILD_REVISION="mym4_revision" ----------------------------------------------------------------------- Summary of changes: Makefile.am | 12 +++++++++--- configure.ac | 12 +++++++++++- 2 files changed, 20 insertions(+), 4 deletions(-) hooks/post-receive -- The GNU crypto library http://git.gnupg.org _______________________________________________ Gnupg-commits mailing list Gnupg-commits at gnupg.org http://lists.gnupg.org/mailman/listinfo/gnupg-commits From wk at gnupg.org Mon Dec 15 12:29:30 2014 From: wk at gnupg.org (Werner Koch) Date: Mon, 15 Dec 2014 12:29:30 +0100 Subject: [PATCH] rijndael: use more compact look-up tables and add table prefetching In-Reply-To: <20141212225227.1465.65893.stgit@localhost6.localdomain6> (Jussi Kivilinna's message of "Sat, 13 Dec 2014 00:52:27 +0200") References: <20141212225227.1465.65893.stgit@localhost6.localdomain6> Message-ID: <87vbldi21x.fsf@vigenere.g10code.de> On Fri, 12 Dec 2014 23:52, jussi.kivilinna at iki.fi said: > AMD64 assembly is slower than before because of additional rotation > instructions. The generic C implementation is new better optimized and > actually faster than before. Can you explain why we want a slower implementation of AESNI? Make side-channel attacks harder? Salam-Shalom, Werner -- Die Gedanken sind frei. Ausnahmen regelt ein Bundesgesetz. From jussi.kivilinna at iki.fi Mon Dec 15 16:47:52 2014 From: jussi.kivilinna at iki.fi (Jussi Kivilinna) Date: Mon, 15 Dec 2014 17:47:52 +0200 Subject: [PATCH] rijndael: use more compact look-up tables and add table prefetching In-Reply-To: <87vbldi21x.fsf@vigenere.g10code.de> References: <20141212225227.1465.65893.stgit@localhost6.localdomain6> <87vbldi21x.fsf@vigenere.g10code.de> Message-ID: <548F02A8.5010202@iki.fi> On 2014-12-15 13:29, Werner Koch wrote: > On Fri, 12 Dec 2014 23:52, jussi.kivilinna at iki.fi said: > >> AMD64 assembly is slower than before because of additional rotation >> instructions. The generic C implementation is new better optimized and >> actually faster than before. > > Can you explain why we want a slower implementation of AESNI? Make > side-channel attacks harder? > AMD64 assembly implementation is different (rijndael-amd64.S) from AES-NI implementation (rijndael-aesni.c). AES-NI has not been changed by this patch and has same performance as before. -Jussi > > Salam-Shalom, > > Werner > From wk at gnupg.org Mon Dec 15 19:55:56 2014 From: wk at gnupg.org (Werner Koch) Date: Mon, 15 Dec 2014 19:55:56 +0100 Subject: [PATCH] rijndael: use more compact look-up tables and add table prefetching In-Reply-To: <548F02A8.5010202@iki.fi> (Jussi Kivilinna's message of "Mon, 15 Dec 2014 17:47:52 +0200") References: <20141212225227.1465.65893.stgit@localhost6.localdomain6> <87vbldi21x.fsf@vigenere.g10code.de> <548F02A8.5010202@iki.fi> Message-ID: <87egs0hhdv.fsf@vigenere.g10code.de> On Mon, 15 Dec 2014 16:47, jussi.kivilinna at iki.fi said: > AMD64 assembly implementation is different (rijndael-amd64.S) from > AES-NI implementation (rijndael-aesni.c). AES-NI has not been changed by Okay. Shalom-Salam, Werner -- Die Gedanken sind frei. Ausnahmen regelt ein Bundesgesetz. From maxim.suraev at campus.tu-berlin.de Thu Dec 18 17:06:18 2014 From: maxim.suraev at campus.tu-berlin.de (Max) Date: Thu, 18 Dec 2014 17:06:18 +0100 Subject: hex conversion Message-ID: <5492FB7A.2030704@campus.tu-berlin.de> Hi all. After some basic experimentation with libgcrypt and reading through API docs it seems like just the thing I need. However one utility piece seems to be missing - conversion to and from hexadecimal strings. For example I receive data as a command-line argument, calculate hash from it and print it onto the screen: ./a.out 39ef13c5aaaaaaaaaaaaaaaaa test hash: 2b567dd47b587955f1a83f60f94138ad I can use gcry_md_hash_buffer(...) but first I've got to prepare buffer, so I need to convert ascii string "39ef13c5aaaaaaaaaaaaaaaaa" into hexadecimal uint8_t * buffer. Similarly, I've got to convert resulting digest into proper ascii representation. Am I missing something obvious or every user of libgcrypt writes its own hex2bin() and bin2hex() functions? best regards, Max. From jussi.kivilinna at iki.fi Sat Dec 20 16:21:29 2014 From: jussi.kivilinna at iki.fi (Jussi Kivilinna) Date: Sat, 20 Dec 2014 17:21:29 +0200 Subject: [PATCH] gcm: do not pass extra key pointer for setupM/fillM Message-ID: <20141220152129.29940.83022.stgit@localhost6.localdomain6> * cipher/cipher-gcm-intel-pclmul.c (_gcry_ghash_setup_intel_pclmul): Remove 'h' parameter. * cipher/cipher-gcm.c (_gcry_ghash_setup_intel_pclmul): Ditto. (fillM): Get 'h' pointer from 'c'. (setupM): Remome 'h' parameter. (_gcry_cipher_gcm_setkey): Only pass 'c' to setupM. -- Signed-off-by: Jussi Kivilinna --- cipher/cipher-gcm-intel-pclmul.c | 2 +- cipher/cipher-gcm.c | 15 ++++++++------- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/cipher/cipher-gcm-intel-pclmul.c b/cipher/cipher-gcm-intel-pclmul.c index 02e7701..0314458 100644 --- a/cipher/cipher-gcm-intel-pclmul.c +++ b/cipher/cipher-gcm-intel-pclmul.c @@ -239,7 +239,7 @@ static inline void gfmul_pclmul_aggr4(void) void -_gcry_ghash_setup_intel_pclmul (gcry_cipher_hd_t c, byte *h) +_gcry_ghash_setup_intel_pclmul (gcry_cipher_hd_t c) { u64 tmp[2]; diff --git a/cipher/cipher-gcm.c b/cipher/cipher-gcm.c index f89b81e..6b13fc5 100644 --- a/cipher/cipher-gcm.c +++ b/cipher/cipher-gcm.c @@ -31,7 +31,7 @@ #ifdef GCM_USE_INTEL_PCLMUL -extern void _gcry_ghash_setup_intel_pclmul (gcry_cipher_hd_t c, byte *h); +extern void _gcry_ghash_setup_intel_pclmul (gcry_cipher_hd_t c); extern unsigned int _gcry_ghash_intel_pclmul (gcry_cipher_hd_t c, byte *result, const byte *buf, size_t nblocks); @@ -286,7 +286,8 @@ do_ghash (unsigned char *result, const unsigned char *buf, const u32 *gcmM) } #endif /* !HAVE_U64_TYPEDEF || SIZEOF_UNSIGNED_LONG != 8 */ -#define fillM(c, h) do_fillM (h, c->u_mode.gcm.gcm_table) +#define fillM(c) \ + do_fillM (c->u_mode.gcm.u_ghash_key.key, c->u_mode.gcm.gcm_table) #define GHASH(c, result, buf) do_ghash (result, buf, c->u_mode.gcm.gcm_table) #else @@ -351,7 +352,7 @@ do_ghash (unsigned char *hsub, unsigned char *result, const unsigned char *buf) return (sizeof(V) + sizeof(T) + sizeof(int)*2 + sizeof(void*)*5); } -#define fillM(c, h) do { } while (0) +#define fillM(c) do { } while (0) #define GHASH(c, result, buf) do_ghash (c->u_mode.gcm.u_ghash_key.key, result, buf) #endif /* !GCM_USE_TABLES */ @@ -376,7 +377,7 @@ ghash_internal (gcry_cipher_hd_t c, byte *result, const byte *buf, static void -setupM (gcry_cipher_hd_t c, byte *h) +setupM (gcry_cipher_hd_t c) { if (0) ; @@ -384,13 +385,13 @@ setupM (gcry_cipher_hd_t c, byte *h) else if (_gcry_get_hw_features () & HWF_INTEL_PCLMUL) { c->u_mode.gcm.ghash_fn = _gcry_ghash_intel_pclmul; - _gcry_ghash_setup_intel_pclmul(c, h); + _gcry_ghash_setup_intel_pclmul (c); } #endif else { c->u_mode.gcm.ghash_fn = ghash_internal; - fillM (c, h); + fillM (c); } } @@ -643,7 +644,7 @@ _gcry_cipher_gcm_setkey (gcry_cipher_hd_t c) c->spec->encrypt (&c->context.c, c->u_mode.gcm.u_ghash_key.key, c->u_mode.gcm.u_ghash_key.key); - setupM (c, c->u_mode.gcm.u_ghash_key.key); + setupM (c); } From jussi.kivilinna at iki.fi Sat Dec 20 15:53:08 2014 From: jussi.kivilinna at iki.fi (Jussi Kivilinna) Date: Sat, 20 Dec 2014 16:53:08 +0200 Subject: [PATCH v2] rijndael: use more compact look-up tables and add table prefetching In-Reply-To: <20141212225227.1465.65893.stgit@localhost6.localdomain6> References: <20141212225227.1465.65893.stgit@localhost6.localdomain6> Message-ID: <20141220145308.32217.12353.stgit@localhost6.localdomain6> * cipher/rijndael-internal.h (rijndael_prefetchfn_t): New. (RIJNDAEL_context): Add 'prefetch_enc_fn' and 'prefetch_dec_fn'. * cipher/rijndael-tables.h (S, T1, T2, T3, T4, T5, T6, T7, T8, S5, U1) (U2, U3, U4): Remove. (encT, dec_tables, decT, inv_sbox): Add. * cipher/rijndael.c (_gcry_aes_amd64_encrypt_block) (_gcry_aes_amd64_decrypt_block, _gcry_aes_arm_encrypt_block) (_gcry_aes_arm_encrypt_block): Add parameter for passing table pointer to assembly implementation. (prefetch_table, prefetch_enc, prefetch_dec): New. (do_setkey): Setup context prefetch functions depending on selected rijndael implementation; Use new tables for key setup. (prepare_decryption): Use new tables for decryption key setup. (do_encrypt_aligned): Rename to... (do_encrypt_fn): ... to this, change to use new compact tables, make handle unaligned input and unroll rounds loop by two. (do_encrypt): Remove handling of unaligned input/output; pass table pointer to assembly implementations. (rijndael_encrypt, _gcry_aes_cfb_enc, _gcry_aes_cbc_enc) (_gcry_aes_ctr_enc, _gcry_aes_cfb_dec): Prefetch encryption tables before encryption. (do_decrypt_aligned): Rename to... (do_decrypt_fn): ... to this, change to use new compact tables, make handle unaligned input and unroll rounds loop by two. (do_decrypt): Remove handling of unaligned input/output; pass table pointer to assembly implementations. (rijndael_decrypt, _gcry_aes_cbc_dec): Prefetch decryption tables before decryption. * cipher/rijndael-amd64.S: Use 1+1.25 KiB tables for encryption+decryption; remove tables from assembly file. * cipher/rijndael-arm.S: Ditto. -- Patch replaces 4+4.25 KiB look-up tables in generic implementation and 8+8 KiB look-up tables in AMD64 implementation and 2+2 KiB look-up tables in ARM implementation with 1+1.25 KiB look-up tables, and adds prefetching of look-up tables. AMD64 assembly is slower than before because of additional rotation instructions. The generic C implementation is now better optimized and actually faster than before. Benchmark results on Intel i5-4570 (turbo off) (64-bit, AMD64 assembly): tests/bench-slope --disable-hwf intel-aesni --cpu-mhz 3200 cipher aes Old: AES | nanosecs/byte mebibytes/sec cycles/byte ECB enc | 3.10 ns/B 307.5 MiB/s 9.92 c/B ECB dec | 3.15 ns/B 302.5 MiB/s 10.09 c/B CBC enc | 3.46 ns/B 275.5 MiB/s 11.08 c/B CBC dec | 3.19 ns/B 299.2 MiB/s 10.20 c/B CFB enc | 3.48 ns/B 274.4 MiB/s 11.12 c/B CFB dec | 3.23 ns/B 294.8 MiB/s 10.35 c/B OFB enc | 3.29 ns/B 290.2 MiB/s 10.52 c/B OFB dec | 3.31 ns/B 288.3 MiB/s 10.58 c/B CTR enc | 3.64 ns/B 261.7 MiB/s 11.66 c/B CTR dec | 3.65 ns/B 261.6 MiB/s 11.67 c/B New: AES | nanosecs/byte mebibytes/sec cycles/byte ECB enc | 4.21 ns/B 226.7 MiB/s 13.46 c/B ECB dec | 4.27 ns/B 223.2 MiB/s 13.67 c/B CBC enc | 4.15 ns/B 229.8 MiB/s 13.28 c/B CBC dec | 3.85 ns/B 247.8 MiB/s 12.31 c/B CFB enc | 4.16 ns/B 229.1 MiB/s 13.32 c/B CFB dec | 3.88 ns/B 245.9 MiB/s 12.41 c/B OFB enc | 4.38 ns/B 217.8 MiB/s 14.01 c/B OFB dec | 4.36 ns/B 218.6 MiB/s 13.96 c/B CTR enc | 4.30 ns/B 221.6 MiB/s 13.77 c/B CTR dec | 4.30 ns/B 221.7 MiB/s 13.76 c/B Benchmark on Intel i5-4570 (turbo off) (32-bit mingw, generic C): tests/bench-slope.exe --disable-hwf intel-aesni --cpu-mhz 3200 cipher aes Old: AES | nanosecs/byte mebibytes/sec cycles/byte ECB enc | 6.03 ns/B 158.2 MiB/s 19.29 c/B ECB dec | 5.81 ns/B 164.1 MiB/s 18.60 c/B CBC enc | 6.22 ns/B 153.4 MiB/s 19.90 c/B CBC dec | 5.91 ns/B 161.3 MiB/s 18.92 c/B CFB enc | 6.25 ns/B 152.7 MiB/s 19.99 c/B CFB dec | 6.24 ns/B 152.8 MiB/s 19.97 c/B OFB enc | 6.33 ns/B 150.6 MiB/s 20.27 c/B OFB dec | 6.33 ns/B 150.7 MiB/s 20.25 c/B CTR enc | 6.28 ns/B 152.0 MiB/s 20.08 c/B CTR dec | 6.28 ns/B 151.7 MiB/s 20.11 c/B New: AES | nanosecs/byte mebibytes/sec cycles/byte ECB enc | 5.02 ns/B 190.0 MiB/s 16.06 c/B ECB dec | 5.33 ns/B 178.8 MiB/s 17.07 c/B CBC enc | 4.64 ns/B 205.4 MiB/s 14.86 c/B CBC dec | 4.95 ns/B 192.7 MiB/s 15.84 c/B CFB enc | 4.75 ns/B 200.7 MiB/s 15.20 c/B CFB dec | 4.74 ns/B 201.1 MiB/s 15.18 c/B OFB enc | 5.29 ns/B 180.3 MiB/s 16.93 c/B OFB dec | 5.29 ns/B 180.3 MiB/s 16.93 c/B CTR enc | 4.77 ns/B 200.0 MiB/s 15.26 c/B CTR dec | 4.77 ns/B 199.8 MiB/s 15.27 c/B Benchmark on Cortex-A8 (ARM assembly): tests/bench-slope --cpu-mhz 1008 cipher aes Old: AES | nanosecs/byte mebibytes/sec cycles/byte ECB enc | 21.84 ns/B 43.66 MiB/s 22.02 c/B ECB dec | 22.35 ns/B 42.67 MiB/s 22.53 c/B CBC enc | 22.97 ns/B 41.53 MiB/s 23.15 c/B CBC dec | 23.48 ns/B 40.61 MiB/s 23.67 c/B CFB enc | 22.72 ns/B 41.97 MiB/s 22.90 c/B CFB dec | 23.41 ns/B 40.74 MiB/s 23.59 c/B OFB enc | 23.65 ns/B 40.32 MiB/s 23.84 c/B OFB dec | 23.67 ns/B 40.29 MiB/s 23.86 c/B CTR enc | 23.24 ns/B 41.03 MiB/s 23.43 c/B CTR dec | 23.23 ns/B 41.05 MiB/s 23.42 c/B New: AES | nanosecs/byte mebibytes/sec cycles/byte ECB enc | 26.03 ns/B 36.64 MiB/s 26.24 c/B ECB dec | 26.97 ns/B 35.36 MiB/s 27.18 c/B CBC enc | 23.21 ns/B 41.09 MiB/s 23.39 c/B CBC dec | 23.36 ns/B 40.83 MiB/s 23.54 c/B CFB enc | 23.02 ns/B 41.42 MiB/s 23.21 c/B CFB dec | 23.67 ns/B 40.28 MiB/s 23.86 c/B OFB enc | 27.86 ns/B 34.24 MiB/s 28.08 c/B OFB dec | 27.87 ns/B 34.21 MiB/s 28.10 c/B CTR enc | 23.47 ns/B 40.63 MiB/s 23.66 c/B CTR dec | 23.49 ns/B 40.61 MiB/s 23.67 c/B -- Changes for patch v2: - Use 1+1.25 KiB tables instead of 2+2 KiB. - Performance measured with CPU turbo off (cpb comparable with v1) Signed-off-by: Jussi Kivilinna --- cipher/rijndael-amd64.S | 1276 ++++--------------------------- cipher/rijndael-arm.S | 500 +++--------- cipher/rijndael-internal.h | 3 cipher/rijndael-tables.h | 1822 ++++---------------------------------------- cipher/rijndael.c | 645 +++++++++------- 5 files changed, 820 insertions(+), 3426 deletions(-) diff --git a/cipher/rijndael-amd64.S b/cipher/rijndael-amd64.S index 90e804b..24c555a 100644 --- a/cipher/rijndael-amd64.S +++ b/cipher/rijndael-amd64.S @@ -31,25 +31,15 @@ .text /* table macros */ -#define E0 (.LtableE0-.LtableE0) -#define E1 (.LtableE1-.LtableE0) -#define E2 (.LtableE2-.LtableE0) -#define E3 (.LtableE3-.LtableE0) -#define Es0 (.LtableEs0-.LtableE0) -#define Es1 (.LtableEs1-.LtableE0) -#define Es2 (.LtableEs2-.LtableE0) -#define Es3 (.LtableEs3-.LtableE0) -#define Esize 8 +#define E0 (0) +#define Es0 (1) +#define Esize 4 +#define Essize 4 -#define D0 (.LtableD0-.LtableD0) -#define D1 (.LtableD1-.LtableD0) -#define D2 (.LtableD2-.LtableD0) -#define D3 (.LtableD3-.LtableD0) -#define Ds0 (.LtableDs0-.LtableD0) -#define Ds1 (.LtableDs1-.LtableD0) -#define Ds2 (.LtableDs2-.LtableD0) -#define Ds3 (.LtableDs3-.LtableD0) -#define Dsize 8 +#define D0 (0) +#define Ds0 (4 * 256) +#define Dsize 4 +#define Dssize 1 /* register macros */ #define CTX %rdi @@ -93,8 +83,8 @@ /* helper macros */ #define do16bit(op, source, tablemul, table1, dest1, table2, dest2, t0, t1) \ - movzbl source ## bh, t1 ## d; \ movzbl source ## bl, t0 ## d; \ + movzbl source ## bh, t1 ## d; \ op ## l table1(RTAB,t0,tablemul), dest1 ## d; \ op ## l table2(RTAB,t1,tablemul), dest2 ## d; @@ -105,6 +95,23 @@ op ## l table1(RTAB,t0,tablemul), dest1 ## d; \ op ## l table2(RTAB,t1,tablemul), dest2 ## d; +#define last_do16bit(op, source, tablemul, table1, dest1, table2, dest2, t0, t1) \ + movzbl source ## bl, t0 ## d; \ + movzbl source ## bh, t1 ## d; \ + movzbl table1(RTAB,t0,tablemul), t0 ## d; \ + movzbl table2(RTAB,t1,tablemul), t1 ## d; \ + op ## l t0 ## d, dest1 ## d; \ + op ## l t1 ## d, dest2 ## d; + +#define last_do16bit_shr(shf, op, source, tablemul, table1, dest1, table2, dest2, t0, t1) \ + movzbl source ## bl, t0 ## d; \ + movzbl source ## bh, t1 ## d; \ + shrl $(shf), source ## d; \ + movzbl table1(RTAB,t0,tablemul), t0 ## d; \ + movzbl table2(RTAB,t1,tablemul), t1 ## d; \ + op ## l t0 ## d, dest1 ## d; \ + op ## l t1 ## d, dest2 ## d; + /*********************************************************************** * AMD64 assembly implementation of the AES cipher ***********************************************************************/ @@ -115,38 +122,76 @@ xorl (((round) * 16) + 3 * 4)(CTX), rd ## d; #define do_encround(next_r) \ - do16bit_shr(16, mov, RA, Esize, E0, RNA, E1, RND, RT0, RT1); \ - do16bit( mov, RA, Esize, E2, RNC, E3, RNB, RT0, RT1); \ + do16bit_shr(16, mov, RA, Esize, E0, RNA, E0, RND, RT0, RT1); \ + do16bit( mov, RA, Esize, E0, RNC, E0, RNB, RT0, RT1); \ movl (((next_r) * 16) + 0 * 4)(CTX), RAd; \ + roll $8, RNDd; \ xorl RNAd, RAd; \ + roll $8, RNCd; \ + roll $8, RNBd; \ + roll $8, RAd; \ \ - do16bit_shr(16, xor, RD, Esize, E0, RND, E1, RNC, RT0, RT1); \ - do16bit( xor, RD, Esize, E2, RNB, E3, RA, RT0, RT1); \ + do16bit_shr(16, xor, RD, Esize, E0, RND, E0, RNC, RT0, RT1); \ + do16bit( xor, RD, Esize, E0, RNB, E0, RA, RT0, RT1); \ movl (((next_r) * 16) + 3 * 4)(CTX), RDd; \ + roll $8, RNCd; \ xorl RNDd, RDd; \ + roll $8, RNBd; \ + roll $8, RAd; \ + roll $8, RDd; \ \ - do16bit_shr(16, xor, RC, Esize, E0, RNC, E1, RNB, RT0, RT1); \ - do16bit( xor, RC, Esize, E2, RA, E3, RD, RT0, RT1); \ + do16bit_shr(16, xor, RC, Esize, E0, RNC, E0, RNB, RT0, RT1); \ + do16bit( xor, RC, Esize, E0, RA, E0, RD, RT0, RT1); \ movl (((next_r) * 16) + 2 * 4)(CTX), RCd; \ + roll $8, RNBd; \ xorl RNCd, RCd; \ + roll $8, RAd; \ + roll $8, RDd; \ + roll $8, RCd; \ \ - do16bit_shr(16, xor, RB, Esize, E0, RNB, E1, RA, RT0, RT1); \ - do16bit( xor, RB, Esize, E2, RD, E3, RC, RT0, RT1); \ + do16bit_shr(16, xor, RB, Esize, E0, RNB, E0, RA, RT0, RT1); \ + do16bit( xor, RB, Esize, E0, RD, E0, RC, RT0, RT1); \ movl (((next_r) * 16) + 1 * 4)(CTX), RBd; \ - xorl RNBd, RBd; + roll $8, RAd; \ + xorl RNBd, RBd; \ + roll $16, RDd; \ + roll $24, RCd; #define do_lastencround(next_r) \ - do16bit_shr(16, mov, RA, Esize, Es0, RNA, Es1, RND, RT0, RT1); \ - do16bit( mov, RA, Esize, Es2, RNC, Es3, RNB, RT0, RT1); \ + do16bit_shr(16, movzb, RA, Essize, Es0, RNA, Es0, RND, RT0, RT1); \ + do16bit( movzb, RA, Essize, Es0, RNC, Es0, RNB, RT0, RT1); \ + movl (((next_r) * 16) + 0 * 4)(CTX), RAd; \ + roll $8, RNDd; \ + xorl RNAd, RAd; \ + roll $8, RNCd; \ + roll $8, RNBd; \ + roll $8, RAd; \ \ - do16bit_shr(16, or, RB, Esize, Es0, RNB, Es1, RNA, RT0, RT1); \ - do16bit( or, RB, Esize, Es2, RND, Es3, RNC, RT0, RT1); \ + last_do16bit_shr(16, xor, RD, Essize, Es0, RND, Es0, RNC, RT0, RT1); \ + last_do16bit( xor, RD, Essize, Es0, RNB, Es0, RA, RT0, RT1); \ + movl (((next_r) * 16) + 3 * 4)(CTX), RDd; \ + roll $8, RNCd; \ + xorl RNDd, RDd; \ + roll $8, RNBd; \ + roll $8, RAd; \ + roll $8, RDd; \ \ - do16bit_shr(16, or, RC, Esize, Es0, RNC, Es1, RNB, RT0, RT1); \ - do16bit( or, RC, Esize, Es2, RNA, Es3, RND, RT0, RT1); \ + last_do16bit_shr(16, xor, RC, Essize, Es0, RNC, Es0, RNB, RT0, RT1); \ + last_do16bit( xor, RC, Essize, Es0, RA, Es0, RD, RT0, RT1); \ + movl (((next_r) * 16) + 2 * 4)(CTX), RCd; \ + roll $8, RNBd; \ + xorl RNCd, RCd; \ + roll $8, RAd; \ + roll $8, RDd; \ + roll $8, RCd; \ \ - do16bit_shr(16, or, RD, Esize, Es0, RND, Es1, RNC, RT0, RT1); \ - do16bit( or, RD, Esize, Es2, RNB, Es3, RNA, RT0, RT1); + last_do16bit_shr(16, xor, RB, Essize, Es0, RNB, Es0, RA, RT0, RT1); \ + last_do16bit( xor, RB, Essize, Es0, RD, Es0, RC, RT0, RT1); \ + movl (((next_r) * 16) + 1 * 4)(CTX), RBd; \ + roll $8, RAd; \ + xorl RNBd, RBd; \ + roll $16, RDd; \ + roll $24, RCd; #define firstencround(round) \ addroundkey(round, RA, RB, RC, RD); \ @@ -156,8 +201,7 @@ do_encround((round) + 1); #define lastencround(round) \ - do_lastencround(); \ - addroundkey((round) + 1, RNA, RNB, RNC, RND); + do_lastencround((round) + 1); .align 8 .globl _gcry_aes_amd64_encrypt_block @@ -169,6 +213,7 @@ _gcry_aes_amd64_encrypt_block: * %rsi: dst * %rdx: src * %ecx: number of rounds.. 10, 12 or 14 + * %r8: encryption tables */ subq $(5 * 8), %rsp; movq %rsi, (0 * 8)(%rsp); @@ -177,7 +222,7 @@ _gcry_aes_amd64_encrypt_block: movq %rbx, (3 * 8)(%rsp); movq %r12, (4 * 8)(%rsp); - leaq .LtableE0 RIP, RTAB; + leaq (%r8), RTAB; /* read input block */ movl 0 * 4(%rdx), RAd; @@ -202,17 +247,17 @@ _gcry_aes_amd64_encrypt_block: .Lenc_done: /* write output block */ movq (0 * 8)(%rsp), %rsi; - movl RNAd, 0 * 4(%rsi); - movl RNBd, 1 * 4(%rsi); - movl RNCd, 2 * 4(%rsi); - movl RNDd, 3 * 4(%rsi); + movl RAd, 0 * 4(%rsi); + movl RBd, 1 * 4(%rsi); + movl RCd, 2 * 4(%rsi); + movl RDd, 3 * 4(%rsi); movq (4 * 8)(%rsp), %r12; movq (3 * 8)(%rsp), %rbx; movq (2 * 8)(%rsp), %rbp; addq $(5 * 8), %rsp; - movl $(6 * 8), %eax; + movl $(6 * 8), %eax; ret; .align 4 @@ -237,38 +282,76 @@ _gcry_aes_amd64_encrypt_block: .size _gcry_aes_amd64_encrypt_block,.-_gcry_aes_amd64_encrypt_block; #define do_decround(next_r) \ - do16bit_shr(16, mov, RA, Dsize, D0, RNA, D1, RNB, RT0, RT1); \ - do16bit( mov, RA, Dsize, D2, RNC, D3, RND, RT0, RT1); \ + do16bit_shr(16, mov, RA, Dsize, D0, RNA, D0, RNB, RT0, RT1); \ + do16bit( mov, RA, Dsize, D0, RNC, D0, RND, RT0, RT1); \ movl (((next_r) * 16) + 0 * 4)(CTX), RAd; \ + roll $8, RNBd; \ xorl RNAd, RAd; \ + roll $8, RNCd; \ + roll $8, RNDd; \ + roll $8, RAd; \ \ - do16bit_shr(16, xor, RB, Dsize, D0, RNB, D1, RNC, RT0, RT1); \ - do16bit( xor, RB, Dsize, D2, RND, D3, RA, RT0, RT1); \ + do16bit_shr(16, xor, RB, Dsize, D0, RNB, D0, RNC, RT0, RT1); \ + do16bit( xor, RB, Dsize, D0, RND, D0, RA, RT0, RT1); \ movl (((next_r) * 16) + 1 * 4)(CTX), RBd; \ + roll $8, RNCd; \ xorl RNBd, RBd; \ + roll $8, RNDd; \ + roll $8, RAd; \ + roll $8, RBd; \ \ - do16bit_shr(16, xor, RC, Dsize, D0, RNC, D1, RND, RT0, RT1); \ - do16bit( xor, RC, Dsize, D2, RA, D3, RB, RT0, RT1); \ + do16bit_shr(16, xor, RC, Dsize, D0, RNC, D0, RND, RT0, RT1); \ + do16bit( xor, RC, Dsize, D0, RA, D0, RB, RT0, RT1); \ movl (((next_r) * 16) + 2 * 4)(CTX), RCd; \ + roll $8, RNDd; \ xorl RNCd, RCd; \ + roll $8, RAd; \ + roll $8, RBd; \ + roll $8, RCd; \ \ - do16bit_shr(16, xor, RD, Dsize, D0, RND, D1, RA, RT0, RT1); \ - do16bit( xor, RD, Dsize, D2, RB, D3, RC, RT0, RT1); \ + do16bit_shr(16, xor, RD, Dsize, D0, RND, D0, RA, RT0, RT1); \ + do16bit( xor, RD, Dsize, D0, RB, D0, RC, RT0, RT1); \ movl (((next_r) * 16) + 3 * 4)(CTX), RDd; \ + roll $8, RAd; \ xorl RNDd, RDd; \ + roll $16, RBd; \ + roll $24, RCd; -#define do_lastdecround() \ - do16bit_shr(16, mov, RA, Dsize, Ds0, RNA, Ds1, RNB, RT0, RT1); \ - do16bit( mov, RA, Dsize, Ds2, RNC, Ds3, RND, RT0, RT1); \ +#define do_lastdecround(next_r) \ + do16bit_shr(16, movzb, RA, Dssize, Ds0, RNA, Ds0, RNB, RT0, RT1); \ + do16bit( movzb, RA, Dssize, Ds0, RNC, Ds0, RND, RT0, RT1); \ + movl (((next_r) * 16) + 0 * 4)(CTX), RAd; \ + roll $8, RNBd; \ + xorl RNAd, RAd; \ + roll $8, RNCd; \ + roll $8, RNDd; \ + roll $8, RAd; \ \ - do16bit_shr(16, or, RB, Dsize, Ds0, RNB, Ds1, RNC, RT0, RT1); \ - do16bit( or, RB, Dsize, Ds2, RND, Ds3, RNA, RT0, RT1); \ + last_do16bit_shr(16, xor, RB, Dssize, Ds0, RNB, Ds0, RNC, RT0, RT1); \ + last_do16bit( xor, RB, Dssize, Ds0, RND, Ds0, RA, RT0, RT1); \ + movl (((next_r) * 16) + 1 * 4)(CTX), RBd; \ + roll $8, RNCd; \ + xorl RNBd, RBd; \ + roll $8, RNDd; \ + roll $8, RAd; \ + roll $8, RBd; \ \ - do16bit_shr(16, or, RC, Dsize, Ds0, RNC, Ds1, RND, RT0, RT1); \ - do16bit( or, RC, Dsize, Ds2, RNA, Ds3, RNB, RT0, RT1); \ + last_do16bit_shr(16, xor, RC, Dssize, Ds0, RNC, Ds0, RND, RT0, RT1); \ + last_do16bit( xor, RC, Dssize, Ds0, RA, Ds0, RB, RT0, RT1); \ + movl (((next_r) * 16) + 2 * 4)(CTX), RCd; \ + roll $8, RNDd; \ + xorl RNCd, RCd; \ + roll $8, RAd; \ + roll $8, RBd; \ + roll $8, RCd; \ \ - do16bit_shr(16, or, RD, Dsize, Ds0, RND, Ds1, RNA, RT0, RT1); \ - do16bit( or, RD, Dsize, Ds2, RNB, Ds3, RNC, RT0, RT1); + last_do16bit_shr(16, xor, RD, Dssize, Ds0, RND, Ds0, RA, RT0, RT1); \ + last_do16bit( xor, RD, Dssize, Ds0, RB, Ds0, RC, RT0, RT1); \ + movl (((next_r) * 16) + 3 * 4)(CTX), RDd; \ + roll $8, RAd; \ + xorl RNDd, RDd; \ + roll $16, RBd; \ + roll $24, RCd; #define firstdecround(round) \ addroundkey((round + 1), RA, RB, RC, RD); \ @@ -278,8 +361,7 @@ _gcry_aes_amd64_encrypt_block: do_decround(round); #define lastdecround(round) \ - do_lastdecround(); \ - addroundkey(round, RNA, RNB, RNC, RND); + do_lastdecround(round); .align 8 .globl _gcry_aes_amd64_decrypt_block @@ -291,6 +373,7 @@ _gcry_aes_amd64_decrypt_block: * %rsi: dst * %rdx: src * %ecx: number of rounds.. 10, 12 or 14 + * %r8: decryption tables */ subq $(5 * 8), %rsp; movq %rsi, (0 * 8)(%rsp); @@ -299,7 +382,7 @@ _gcry_aes_amd64_decrypt_block: movq %rbx, (3 * 8)(%rsp); movq %r12, (4 * 8)(%rsp); - leaq .LtableD0 RIP, RTAB; + leaq (%r8), RTAB; /* read input block */ movl 0 * 4(%rdx), RAd; @@ -325,17 +408,17 @@ _gcry_aes_amd64_decrypt_block: /* write output block */ movq (0 * 8)(%rsp), %rsi; - movl RNAd, 0 * 4(%rsi); - movl RNBd, 1 * 4(%rsi); - movl RNCd, 2 * 4(%rsi); - movl RNDd, 3 * 4(%rsi); + movl RAd, 0 * 4(%rsi); + movl RBd, 1 * 4(%rsi); + movl RCd, 2 * 4(%rsi); + movl RDd, 3 * 4(%rsi); movq (4 * 8)(%rsp), %r12; movq (3 * 8)(%rsp), %rbx; movq (2 * 8)(%rsp), %rbp; addq $(5 * 8), %rsp; - movl $(6 * 8), %eax; + movl $(6 * 8), %eax; ret; .align 4 @@ -359,1060 +442,5 @@ _gcry_aes_amd64_decrypt_block: jmp .Ldec_tail; .size _gcry_aes_amd64_decrypt_block,.-_gcry_aes_amd64_decrypt_block; -.data -.align 16 - -/* Encryption tables */ -.LtableE0: -.long 0xa56363c6 -.LtableEs0: -.long 0x00000063, 0x847c7cf8, 0x0000007c -.long 0x997777ee, 0x00000077, 0x8d7b7bf6, 0x0000007b -.long 0x0df2f2ff, 0x000000f2, 0xbd6b6bd6, 0x0000006b -.long 0xb16f6fde, 0x0000006f, 0x54c5c591, 0x000000c5 -.long 0x50303060, 0x00000030, 0x03010102, 0x00000001 -.long 0xa96767ce, 0x00000067, 0x7d2b2b56, 0x0000002b -.long 0x19fefee7, 0x000000fe, 0x62d7d7b5, 0x000000d7 -.long 0xe6abab4d, 0x000000ab, 0x9a7676ec, 0x00000076 -.long 0x45caca8f, 0x000000ca, 0x9d82821f, 0x00000082 -.long 0x40c9c989, 0x000000c9, 0x877d7dfa, 0x0000007d -.long 0x15fafaef, 0x000000fa, 0xeb5959b2, 0x00000059 -.long 0xc947478e, 0x00000047, 0x0bf0f0fb, 0x000000f0 -.long 0xecadad41, 0x000000ad, 0x67d4d4b3, 0x000000d4 -.long 0xfda2a25f, 0x000000a2, 0xeaafaf45, 0x000000af -.long 0xbf9c9c23, 0x0000009c, 0xf7a4a453, 0x000000a4 -.long 0x967272e4, 0x00000072, 0x5bc0c09b, 0x000000c0 -.long 0xc2b7b775, 0x000000b7, 0x1cfdfde1, 0x000000fd -.long 0xae93933d, 0x00000093, 0x6a26264c, 0x00000026 -.long 0x5a36366c, 0x00000036, 0x413f3f7e, 0x0000003f -.long 0x02f7f7f5, 0x000000f7, 0x4fcccc83, 0x000000cc -.long 0x5c343468, 0x00000034, 0xf4a5a551, 0x000000a5 -.long 0x34e5e5d1, 0x000000e5, 0x08f1f1f9, 0x000000f1 -.long 0x937171e2, 0x00000071, 0x73d8d8ab, 0x000000d8 -.long 0x53313162, 0x00000031, 0x3f15152a, 0x00000015 -.long 0x0c040408, 0x00000004, 0x52c7c795, 0x000000c7 -.long 0x65232346, 0x00000023, 0x5ec3c39d, 0x000000c3 -.long 0x28181830, 0x00000018, 0xa1969637, 0x00000096 -.long 0x0f05050a, 0x00000005, 0xb59a9a2f, 0x0000009a -.long 0x0907070e, 0x00000007, 0x36121224, 0x00000012 -.long 0x9b80801b, 0x00000080, 0x3de2e2df, 0x000000e2 -.long 0x26ebebcd, 0x000000eb, 0x6927274e, 0x00000027 -.long 0xcdb2b27f, 0x000000b2, 0x9f7575ea, 0x00000075 -.long 0x1b090912, 0x00000009, 0x9e83831d, 0x00000083 -.long 0x742c2c58, 0x0000002c, 0x2e1a1a34, 0x0000001a -.long 0x2d1b1b36, 0x0000001b, 0xb26e6edc, 0x0000006e -.long 0xee5a5ab4, 0x0000005a, 0xfba0a05b, 0x000000a0 -.long 0xf65252a4, 0x00000052, 0x4d3b3b76, 0x0000003b -.long 0x61d6d6b7, 0x000000d6, 0xceb3b37d, 0x000000b3 -.long 0x7b292952, 0x00000029, 0x3ee3e3dd, 0x000000e3 -.long 0x712f2f5e, 0x0000002f, 0x97848413, 0x00000084 -.long 0xf55353a6, 0x00000053, 0x68d1d1b9, 0x000000d1 -.long 0x00000000, 0x00000000, 0x2cededc1, 0x000000ed -.long 0x60202040, 0x00000020, 0x1ffcfce3, 0x000000fc -.long 0xc8b1b179, 0x000000b1, 0xed5b5bb6, 0x0000005b -.long 0xbe6a6ad4, 0x0000006a, 0x46cbcb8d, 0x000000cb -.long 0xd9bebe67, 0x000000be, 0x4b393972, 0x00000039 -.long 0xde4a4a94, 0x0000004a, 0xd44c4c98, 0x0000004c -.long 0xe85858b0, 0x00000058, 0x4acfcf85, 0x000000cf -.long 0x6bd0d0bb, 0x000000d0, 0x2aefefc5, 0x000000ef -.long 0xe5aaaa4f, 0x000000aa, 0x16fbfbed, 0x000000fb -.long 0xc5434386, 0x00000043, 0xd74d4d9a, 0x0000004d -.long 0x55333366, 0x00000033, 0x94858511, 0x00000085 -.long 0xcf45458a, 0x00000045, 0x10f9f9e9, 0x000000f9 -.long 0x06020204, 0x00000002, 0x817f7ffe, 0x0000007f -.long 0xf05050a0, 0x00000050, 0x443c3c78, 0x0000003c -.long 0xba9f9f25, 0x0000009f, 0xe3a8a84b, 0x000000a8 -.long 0xf35151a2, 0x00000051, 0xfea3a35d, 0x000000a3 -.long 0xc0404080, 0x00000040, 0x8a8f8f05, 0x0000008f -.long 0xad92923f, 0x00000092, 0xbc9d9d21, 0x0000009d -.long 0x48383870, 0x00000038, 0x04f5f5f1, 0x000000f5 -.long 0xdfbcbc63, 0x000000bc, 0xc1b6b677, 0x000000b6 -.long 0x75dadaaf, 0x000000da, 0x63212142, 0x00000021 -.long 0x30101020, 0x00000010, 0x1affffe5, 0x000000ff -.long 0x0ef3f3fd, 0x000000f3, 0x6dd2d2bf, 0x000000d2 -.long 0x4ccdcd81, 0x000000cd, 0x140c0c18, 0x0000000c -.long 0x35131326, 0x00000013, 0x2fececc3, 0x000000ec -.long 0xe15f5fbe, 0x0000005f, 0xa2979735, 0x00000097 -.long 0xcc444488, 0x00000044, 0x3917172e, 0x00000017 -.long 0x57c4c493, 0x000000c4, 0xf2a7a755, 0x000000a7 -.long 0x827e7efc, 0x0000007e, 0x473d3d7a, 0x0000003d -.long 0xac6464c8, 0x00000064, 0xe75d5dba, 0x0000005d -.long 0x2b191932, 0x00000019, 0x957373e6, 0x00000073 -.long 0xa06060c0, 0x00000060, 0x98818119, 0x00000081 -.long 0xd14f4f9e, 0x0000004f, 0x7fdcdca3, 0x000000dc -.long 0x66222244, 0x00000022, 0x7e2a2a54, 0x0000002a -.long 0xab90903b, 0x00000090, 0x8388880b, 0x00000088 -.long 0xca46468c, 0x00000046, 0x29eeeec7, 0x000000ee -.long 0xd3b8b86b, 0x000000b8, 0x3c141428, 0x00000014 -.long 0x79dedea7, 0x000000de, 0xe25e5ebc, 0x0000005e -.long 0x1d0b0b16, 0x0000000b, 0x76dbdbad, 0x000000db -.long 0x3be0e0db, 0x000000e0, 0x56323264, 0x00000032 -.long 0x4e3a3a74, 0x0000003a, 0x1e0a0a14, 0x0000000a -.long 0xdb494992, 0x00000049, 0x0a06060c, 0x00000006 -.long 0x6c242448, 0x00000024, 0xe45c5cb8, 0x0000005c -.long 0x5dc2c29f, 0x000000c2, 0x6ed3d3bd, 0x000000d3 -.long 0xefacac43, 0x000000ac, 0xa66262c4, 0x00000062 -.long 0xa8919139, 0x00000091, 0xa4959531, 0x00000095 -.long 0x37e4e4d3, 0x000000e4, 0x8b7979f2, 0x00000079 -.long 0x32e7e7d5, 0x000000e7, 0x43c8c88b, 0x000000c8 -.long 0x5937376e, 0x00000037, 0xb76d6dda, 0x0000006d -.long 0x8c8d8d01, 0x0000008d, 0x64d5d5b1, 0x000000d5 -.long 0xd24e4e9c, 0x0000004e, 0xe0a9a949, 0x000000a9 -.long 0xb46c6cd8, 0x0000006c, 0xfa5656ac, 0x00000056 -.long 0x07f4f4f3, 0x000000f4, 0x25eaeacf, 0x000000ea -.long 0xaf6565ca, 0x00000065, 0x8e7a7af4, 0x0000007a -.long 0xe9aeae47, 0x000000ae, 0x18080810, 0x00000008 -.long 0xd5baba6f, 0x000000ba, 0x887878f0, 0x00000078 -.long 0x6f25254a, 0x00000025, 0x722e2e5c, 0x0000002e -.long 0x241c1c38, 0x0000001c, 0xf1a6a657, 0x000000a6 -.long 0xc7b4b473, 0x000000b4, 0x51c6c697, 0x000000c6 -.long 0x23e8e8cb, 0x000000e8, 0x7cdddda1, 0x000000dd -.long 0x9c7474e8, 0x00000074, 0x211f1f3e, 0x0000001f -.long 0xdd4b4b96, 0x0000004b, 0xdcbdbd61, 0x000000bd -.long 0x868b8b0d, 0x0000008b, 0x858a8a0f, 0x0000008a -.long 0x907070e0, 0x00000070, 0x423e3e7c, 0x0000003e -.long 0xc4b5b571, 0x000000b5, 0xaa6666cc, 0x00000066 -.long 0xd8484890, 0x00000048, 0x05030306, 0x00000003 -.long 0x01f6f6f7, 0x000000f6, 0x120e0e1c, 0x0000000e -.long 0xa36161c2, 0x00000061, 0x5f35356a, 0x00000035 -.long 0xf95757ae, 0x00000057, 0xd0b9b969, 0x000000b9 -.long 0x91868617, 0x00000086, 0x58c1c199, 0x000000c1 -.long 0x271d1d3a, 0x0000001d, 0xb99e9e27, 0x0000009e -.long 0x38e1e1d9, 0x000000e1, 0x13f8f8eb, 0x000000f8 -.long 0xb398982b, 0x00000098, 0x33111122, 0x00000011 -.long 0xbb6969d2, 0x00000069, 0x70d9d9a9, 0x000000d9 -.long 0x898e8e07, 0x0000008e, 0xa7949433, 0x00000094 -.long 0xb69b9b2d, 0x0000009b, 0x221e1e3c, 0x0000001e -.long 0x92878715, 0x00000087, 0x20e9e9c9, 0x000000e9 -.long 0x49cece87, 0x000000ce, 0xff5555aa, 0x00000055 -.long 0x78282850, 0x00000028, 0x7adfdfa5, 0x000000df -.long 0x8f8c8c03, 0x0000008c, 0xf8a1a159, 0x000000a1 -.long 0x80898909, 0x00000089, 0x170d0d1a, 0x0000000d -.long 0xdabfbf65, 0x000000bf, 0x31e6e6d7, 0x000000e6 -.long 0xc6424284, 0x00000042, 0xb86868d0, 0x00000068 -.long 0xc3414182, 0x00000041, 0xb0999929, 0x00000099 -.long 0x772d2d5a, 0x0000002d, 0x110f0f1e, 0x0000000f -.long 0xcbb0b07b, 0x000000b0, 0xfc5454a8, 0x00000054 -.long 0xd6bbbb6d, 0x000000bb, 0x3a16162c, 0x00000016 -.LtableE1: -.long 0x6363c6a5 -.LtableEs1: -.long 0x00006300, 0x7c7cf884, 0x00007c00 -.long 0x7777ee99, 0x00007700, 0x7b7bf68d, 0x00007b00 -.long 0xf2f2ff0d, 0x0000f200, 0x6b6bd6bd, 0x00006b00 -.long 0x6f6fdeb1, 0x00006f00, 0xc5c59154, 0x0000c500 -.long 0x30306050, 0x00003000, 0x01010203, 0x00000100 -.long 0x6767cea9, 0x00006700, 0x2b2b567d, 0x00002b00 -.long 0xfefee719, 0x0000fe00, 0xd7d7b562, 0x0000d700 -.long 0xabab4de6, 0x0000ab00, 0x7676ec9a, 0x00007600 -.long 0xcaca8f45, 0x0000ca00, 0x82821f9d, 0x00008200 -.long 0xc9c98940, 0x0000c900, 0x7d7dfa87, 0x00007d00 -.long 0xfafaef15, 0x0000fa00, 0x5959b2eb, 0x00005900 -.long 0x47478ec9, 0x00004700, 0xf0f0fb0b, 0x0000f000 -.long 0xadad41ec, 0x0000ad00, 0xd4d4b367, 0x0000d400 -.long 0xa2a25ffd, 0x0000a200, 0xafaf45ea, 0x0000af00 -.long 0x9c9c23bf, 0x00009c00, 0xa4a453f7, 0x0000a400 -.long 0x7272e496, 0x00007200, 0xc0c09b5b, 0x0000c000 -.long 0xb7b775c2, 0x0000b700, 0xfdfde11c, 0x0000fd00 -.long 0x93933dae, 0x00009300, 0x26264c6a, 0x00002600 -.long 0x36366c5a, 0x00003600, 0x3f3f7e41, 0x00003f00 -.long 0xf7f7f502, 0x0000f700, 0xcccc834f, 0x0000cc00 -.long 0x3434685c, 0x00003400, 0xa5a551f4, 0x0000a500 -.long 0xe5e5d134, 0x0000e500, 0xf1f1f908, 0x0000f100 -.long 0x7171e293, 0x00007100, 0xd8d8ab73, 0x0000d800 -.long 0x31316253, 0x00003100, 0x15152a3f, 0x00001500 -.long 0x0404080c, 0x00000400, 0xc7c79552, 0x0000c700 -.long 0x23234665, 0x00002300, 0xc3c39d5e, 0x0000c300 -.long 0x18183028, 0x00001800, 0x969637a1, 0x00009600 -.long 0x05050a0f, 0x00000500, 0x9a9a2fb5, 0x00009a00 -.long 0x07070e09, 0x00000700, 0x12122436, 0x00001200 -.long 0x80801b9b, 0x00008000, 0xe2e2df3d, 0x0000e200 -.long 0xebebcd26, 0x0000eb00, 0x27274e69, 0x00002700 -.long 0xb2b27fcd, 0x0000b200, 0x7575ea9f, 0x00007500 -.long 0x0909121b, 0x00000900, 0x83831d9e, 0x00008300 -.long 0x2c2c5874, 0x00002c00, 0x1a1a342e, 0x00001a00 -.long 0x1b1b362d, 0x00001b00, 0x6e6edcb2, 0x00006e00 -.long 0x5a5ab4ee, 0x00005a00, 0xa0a05bfb, 0x0000a000 -.long 0x5252a4f6, 0x00005200, 0x3b3b764d, 0x00003b00 -.long 0xd6d6b761, 0x0000d600, 0xb3b37dce, 0x0000b300 -.long 0x2929527b, 0x00002900, 0xe3e3dd3e, 0x0000e300 -.long 0x2f2f5e71, 0x00002f00, 0x84841397, 0x00008400 -.long 0x5353a6f5, 0x00005300, 0xd1d1b968, 0x0000d100 -.long 0x00000000, 0x00000000, 0xededc12c, 0x0000ed00 -.long 0x20204060, 0x00002000, 0xfcfce31f, 0x0000fc00 -.long 0xb1b179c8, 0x0000b100, 0x5b5bb6ed, 0x00005b00 -.long 0x6a6ad4be, 0x00006a00, 0xcbcb8d46, 0x0000cb00 -.long 0xbebe67d9, 0x0000be00, 0x3939724b, 0x00003900 -.long 0x4a4a94de, 0x00004a00, 0x4c4c98d4, 0x00004c00 -.long 0x5858b0e8, 0x00005800, 0xcfcf854a, 0x0000cf00 -.long 0xd0d0bb6b, 0x0000d000, 0xefefc52a, 0x0000ef00 -.long 0xaaaa4fe5, 0x0000aa00, 0xfbfbed16, 0x0000fb00 -.long 0x434386c5, 0x00004300, 0x4d4d9ad7, 0x00004d00 -.long 0x33336655, 0x00003300, 0x85851194, 0x00008500 -.long 0x45458acf, 0x00004500, 0xf9f9e910, 0x0000f900 -.long 0x02020406, 0x00000200, 0x7f7ffe81, 0x00007f00 -.long 0x5050a0f0, 0x00005000, 0x3c3c7844, 0x00003c00 -.long 0x9f9f25ba, 0x00009f00, 0xa8a84be3, 0x0000a800 -.long 0x5151a2f3, 0x00005100, 0xa3a35dfe, 0x0000a300 -.long 0x404080c0, 0x00004000, 0x8f8f058a, 0x00008f00 -.long 0x92923fad, 0x00009200, 0x9d9d21bc, 0x00009d00 -.long 0x38387048, 0x00003800, 0xf5f5f104, 0x0000f500 -.long 0xbcbc63df, 0x0000bc00, 0xb6b677c1, 0x0000b600 -.long 0xdadaaf75, 0x0000da00, 0x21214263, 0x00002100 -.long 0x10102030, 0x00001000, 0xffffe51a, 0x0000ff00 -.long 0xf3f3fd0e, 0x0000f300, 0xd2d2bf6d, 0x0000d200 -.long 0xcdcd814c, 0x0000cd00, 0x0c0c1814, 0x00000c00 -.long 0x13132635, 0x00001300, 0xececc32f, 0x0000ec00 -.long 0x5f5fbee1, 0x00005f00, 0x979735a2, 0x00009700 -.long 0x444488cc, 0x00004400, 0x17172e39, 0x00001700 -.long 0xc4c49357, 0x0000c400, 0xa7a755f2, 0x0000a700 -.long 0x7e7efc82, 0x00007e00, 0x3d3d7a47, 0x00003d00 -.long 0x6464c8ac, 0x00006400, 0x5d5dbae7, 0x00005d00 -.long 0x1919322b, 0x00001900, 0x7373e695, 0x00007300 -.long 0x6060c0a0, 0x00006000, 0x81811998, 0x00008100 -.long 0x4f4f9ed1, 0x00004f00, 0xdcdca37f, 0x0000dc00 -.long 0x22224466, 0x00002200, 0x2a2a547e, 0x00002a00 -.long 0x90903bab, 0x00009000, 0x88880b83, 0x00008800 -.long 0x46468cca, 0x00004600, 0xeeeec729, 0x0000ee00 -.long 0xb8b86bd3, 0x0000b800, 0x1414283c, 0x00001400 -.long 0xdedea779, 0x0000de00, 0x5e5ebce2, 0x00005e00 -.long 0x0b0b161d, 0x00000b00, 0xdbdbad76, 0x0000db00 -.long 0xe0e0db3b, 0x0000e000, 0x32326456, 0x00003200 -.long 0x3a3a744e, 0x00003a00, 0x0a0a141e, 0x00000a00 -.long 0x494992db, 0x00004900, 0x06060c0a, 0x00000600 -.long 0x2424486c, 0x00002400, 0x5c5cb8e4, 0x00005c00 -.long 0xc2c29f5d, 0x0000c200, 0xd3d3bd6e, 0x0000d300 -.long 0xacac43ef, 0x0000ac00, 0x6262c4a6, 0x00006200 -.long 0x919139a8, 0x00009100, 0x959531a4, 0x00009500 -.long 0xe4e4d337, 0x0000e400, 0x7979f28b, 0x00007900 -.long 0xe7e7d532, 0x0000e700, 0xc8c88b43, 0x0000c800 -.long 0x37376e59, 0x00003700, 0x6d6ddab7, 0x00006d00 -.long 0x8d8d018c, 0x00008d00, 0xd5d5b164, 0x0000d500 -.long 0x4e4e9cd2, 0x00004e00, 0xa9a949e0, 0x0000a900 -.long 0x6c6cd8b4, 0x00006c00, 0x5656acfa, 0x00005600 -.long 0xf4f4f307, 0x0000f400, 0xeaeacf25, 0x0000ea00 -.long 0x6565caaf, 0x00006500, 0x7a7af48e, 0x00007a00 -.long 0xaeae47e9, 0x0000ae00, 0x08081018, 0x00000800 -.long 0xbaba6fd5, 0x0000ba00, 0x7878f088, 0x00007800 -.long 0x25254a6f, 0x00002500, 0x2e2e5c72, 0x00002e00 -.long 0x1c1c3824, 0x00001c00, 0xa6a657f1, 0x0000a600 -.long 0xb4b473c7, 0x0000b400, 0xc6c69751, 0x0000c600 -.long 0xe8e8cb23, 0x0000e800, 0xdddda17c, 0x0000dd00 -.long 0x7474e89c, 0x00007400, 0x1f1f3e21, 0x00001f00 -.long 0x4b4b96dd, 0x00004b00, 0xbdbd61dc, 0x0000bd00 -.long 0x8b8b0d86, 0x00008b00, 0x8a8a0f85, 0x00008a00 -.long 0x7070e090, 0x00007000, 0x3e3e7c42, 0x00003e00 -.long 0xb5b571c4, 0x0000b500, 0x6666ccaa, 0x00006600 -.long 0x484890d8, 0x00004800, 0x03030605, 0x00000300 -.long 0xf6f6f701, 0x0000f600, 0x0e0e1c12, 0x00000e00 -.long 0x6161c2a3, 0x00006100, 0x35356a5f, 0x00003500 -.long 0x5757aef9, 0x00005700, 0xb9b969d0, 0x0000b900 -.long 0x86861791, 0x00008600, 0xc1c19958, 0x0000c100 -.long 0x1d1d3a27, 0x00001d00, 0x9e9e27b9, 0x00009e00 -.long 0xe1e1d938, 0x0000e100, 0xf8f8eb13, 0x0000f800 -.long 0x98982bb3, 0x00009800, 0x11112233, 0x00001100 -.long 0x6969d2bb, 0x00006900, 0xd9d9a970, 0x0000d900 -.long 0x8e8e0789, 0x00008e00, 0x949433a7, 0x00009400 -.long 0x9b9b2db6, 0x00009b00, 0x1e1e3c22, 0x00001e00 -.long 0x87871592, 0x00008700, 0xe9e9c920, 0x0000e900 -.long 0xcece8749, 0x0000ce00, 0x5555aaff, 0x00005500 -.long 0x28285078, 0x00002800, 0xdfdfa57a, 0x0000df00 -.long 0x8c8c038f, 0x00008c00, 0xa1a159f8, 0x0000a100 -.long 0x89890980, 0x00008900, 0x0d0d1a17, 0x00000d00 -.long 0xbfbf65da, 0x0000bf00, 0xe6e6d731, 0x0000e600 -.long 0x424284c6, 0x00004200, 0x6868d0b8, 0x00006800 -.long 0x414182c3, 0x00004100, 0x999929b0, 0x00009900 -.long 0x2d2d5a77, 0x00002d00, 0x0f0f1e11, 0x00000f00 -.long 0xb0b07bcb, 0x0000b000, 0x5454a8fc, 0x00005400 -.long 0xbbbb6dd6, 0x0000bb00, 0x16162c3a, 0x00001600 -.LtableE2: -.long 0x63c6a563 -.LtableEs2: -.long 0x00630000, 0x7cf8847c, 0x007c0000 -.long 0x77ee9977, 0x00770000, 0x7bf68d7b, 0x007b0000 -.long 0xf2ff0df2, 0x00f20000, 0x6bd6bd6b, 0x006b0000 -.long 0x6fdeb16f, 0x006f0000, 0xc59154c5, 0x00c50000 -.long 0x30605030, 0x00300000, 0x01020301, 0x00010000 -.long 0x67cea967, 0x00670000, 0x2b567d2b, 0x002b0000 -.long 0xfee719fe, 0x00fe0000, 0xd7b562d7, 0x00d70000 -.long 0xab4de6ab, 0x00ab0000, 0x76ec9a76, 0x00760000 -.long 0xca8f45ca, 0x00ca0000, 0x821f9d82, 0x00820000 -.long 0xc98940c9, 0x00c90000, 0x7dfa877d, 0x007d0000 -.long 0xfaef15fa, 0x00fa0000, 0x59b2eb59, 0x00590000 -.long 0x478ec947, 0x00470000, 0xf0fb0bf0, 0x00f00000 -.long 0xad41ecad, 0x00ad0000, 0xd4b367d4, 0x00d40000 -.long 0xa25ffda2, 0x00a20000, 0xaf45eaaf, 0x00af0000 -.long 0x9c23bf9c, 0x009c0000, 0xa453f7a4, 0x00a40000 -.long 0x72e49672, 0x00720000, 0xc09b5bc0, 0x00c00000 -.long 0xb775c2b7, 0x00b70000, 0xfde11cfd, 0x00fd0000 -.long 0x933dae93, 0x00930000, 0x264c6a26, 0x00260000 -.long 0x366c5a36, 0x00360000, 0x3f7e413f, 0x003f0000 -.long 0xf7f502f7, 0x00f70000, 0xcc834fcc, 0x00cc0000 -.long 0x34685c34, 0x00340000, 0xa551f4a5, 0x00a50000 -.long 0xe5d134e5, 0x00e50000, 0xf1f908f1, 0x00f10000 -.long 0x71e29371, 0x00710000, 0xd8ab73d8, 0x00d80000 -.long 0x31625331, 0x00310000, 0x152a3f15, 0x00150000 -.long 0x04080c04, 0x00040000, 0xc79552c7, 0x00c70000 -.long 0x23466523, 0x00230000, 0xc39d5ec3, 0x00c30000 -.long 0x18302818, 0x00180000, 0x9637a196, 0x00960000 -.long 0x050a0f05, 0x00050000, 0x9a2fb59a, 0x009a0000 -.long 0x070e0907, 0x00070000, 0x12243612, 0x00120000 -.long 0x801b9b80, 0x00800000, 0xe2df3de2, 0x00e20000 -.long 0xebcd26eb, 0x00eb0000, 0x274e6927, 0x00270000 -.long 0xb27fcdb2, 0x00b20000, 0x75ea9f75, 0x00750000 -.long 0x09121b09, 0x00090000, 0x831d9e83, 0x00830000 -.long 0x2c58742c, 0x002c0000, 0x1a342e1a, 0x001a0000 -.long 0x1b362d1b, 0x001b0000, 0x6edcb26e, 0x006e0000 -.long 0x5ab4ee5a, 0x005a0000, 0xa05bfba0, 0x00a00000 -.long 0x52a4f652, 0x00520000, 0x3b764d3b, 0x003b0000 -.long 0xd6b761d6, 0x00d60000, 0xb37dceb3, 0x00b30000 -.long 0x29527b29, 0x00290000, 0xe3dd3ee3, 0x00e30000 -.long 0x2f5e712f, 0x002f0000, 0x84139784, 0x00840000 -.long 0x53a6f553, 0x00530000, 0xd1b968d1, 0x00d10000 -.long 0x00000000, 0x00000000, 0xedc12ced, 0x00ed0000 -.long 0x20406020, 0x00200000, 0xfce31ffc, 0x00fc0000 -.long 0xb179c8b1, 0x00b10000, 0x5bb6ed5b, 0x005b0000 -.long 0x6ad4be6a, 0x006a0000, 0xcb8d46cb, 0x00cb0000 -.long 0xbe67d9be, 0x00be0000, 0x39724b39, 0x00390000 -.long 0x4a94de4a, 0x004a0000, 0x4c98d44c, 0x004c0000 -.long 0x58b0e858, 0x00580000, 0xcf854acf, 0x00cf0000 -.long 0xd0bb6bd0, 0x00d00000, 0xefc52aef, 0x00ef0000 -.long 0xaa4fe5aa, 0x00aa0000, 0xfbed16fb, 0x00fb0000 -.long 0x4386c543, 0x00430000, 0x4d9ad74d, 0x004d0000 -.long 0x33665533, 0x00330000, 0x85119485, 0x00850000 -.long 0x458acf45, 0x00450000, 0xf9e910f9, 0x00f90000 -.long 0x02040602, 0x00020000, 0x7ffe817f, 0x007f0000 -.long 0x50a0f050, 0x00500000, 0x3c78443c, 0x003c0000 -.long 0x9f25ba9f, 0x009f0000, 0xa84be3a8, 0x00a80000 -.long 0x51a2f351, 0x00510000, 0xa35dfea3, 0x00a30000 -.long 0x4080c040, 0x00400000, 0x8f058a8f, 0x008f0000 -.long 0x923fad92, 0x00920000, 0x9d21bc9d, 0x009d0000 -.long 0x38704838, 0x00380000, 0xf5f104f5, 0x00f50000 -.long 0xbc63dfbc, 0x00bc0000, 0xb677c1b6, 0x00b60000 -.long 0xdaaf75da, 0x00da0000, 0x21426321, 0x00210000 -.long 0x10203010, 0x00100000, 0xffe51aff, 0x00ff0000 -.long 0xf3fd0ef3, 0x00f30000, 0xd2bf6dd2, 0x00d20000 -.long 0xcd814ccd, 0x00cd0000, 0x0c18140c, 0x000c0000 -.long 0x13263513, 0x00130000, 0xecc32fec, 0x00ec0000 -.long 0x5fbee15f, 0x005f0000, 0x9735a297, 0x00970000 -.long 0x4488cc44, 0x00440000, 0x172e3917, 0x00170000 -.long 0xc49357c4, 0x00c40000, 0xa755f2a7, 0x00a70000 -.long 0x7efc827e, 0x007e0000, 0x3d7a473d, 0x003d0000 -.long 0x64c8ac64, 0x00640000, 0x5dbae75d, 0x005d0000 -.long 0x19322b19, 0x00190000, 0x73e69573, 0x00730000 -.long 0x60c0a060, 0x00600000, 0x81199881, 0x00810000 -.long 0x4f9ed14f, 0x004f0000, 0xdca37fdc, 0x00dc0000 -.long 0x22446622, 0x00220000, 0x2a547e2a, 0x002a0000 -.long 0x903bab90, 0x00900000, 0x880b8388, 0x00880000 -.long 0x468cca46, 0x00460000, 0xeec729ee, 0x00ee0000 -.long 0xb86bd3b8, 0x00b80000, 0x14283c14, 0x00140000 -.long 0xdea779de, 0x00de0000, 0x5ebce25e, 0x005e0000 -.long 0x0b161d0b, 0x000b0000, 0xdbad76db, 0x00db0000 -.long 0xe0db3be0, 0x00e00000, 0x32645632, 0x00320000 -.long 0x3a744e3a, 0x003a0000, 0x0a141e0a, 0x000a0000 -.long 0x4992db49, 0x00490000, 0x060c0a06, 0x00060000 -.long 0x24486c24, 0x00240000, 0x5cb8e45c, 0x005c0000 -.long 0xc29f5dc2, 0x00c20000, 0xd3bd6ed3, 0x00d30000 -.long 0xac43efac, 0x00ac0000, 0x62c4a662, 0x00620000 -.long 0x9139a891, 0x00910000, 0x9531a495, 0x00950000 -.long 0xe4d337e4, 0x00e40000, 0x79f28b79, 0x00790000 -.long 0xe7d532e7, 0x00e70000, 0xc88b43c8, 0x00c80000 -.long 0x376e5937, 0x00370000, 0x6ddab76d, 0x006d0000 -.long 0x8d018c8d, 0x008d0000, 0xd5b164d5, 0x00d50000 -.long 0x4e9cd24e, 0x004e0000, 0xa949e0a9, 0x00a90000 -.long 0x6cd8b46c, 0x006c0000, 0x56acfa56, 0x00560000 -.long 0xf4f307f4, 0x00f40000, 0xeacf25ea, 0x00ea0000 -.long 0x65caaf65, 0x00650000, 0x7af48e7a, 0x007a0000 -.long 0xae47e9ae, 0x00ae0000, 0x08101808, 0x00080000 -.long 0xba6fd5ba, 0x00ba0000, 0x78f08878, 0x00780000 -.long 0x254a6f25, 0x00250000, 0x2e5c722e, 0x002e0000 -.long 0x1c38241c, 0x001c0000, 0xa657f1a6, 0x00a60000 -.long 0xb473c7b4, 0x00b40000, 0xc69751c6, 0x00c60000 -.long 0xe8cb23e8, 0x00e80000, 0xdda17cdd, 0x00dd0000 -.long 0x74e89c74, 0x00740000, 0x1f3e211f, 0x001f0000 -.long 0x4b96dd4b, 0x004b0000, 0xbd61dcbd, 0x00bd0000 -.long 0x8b0d868b, 0x008b0000, 0x8a0f858a, 0x008a0000 -.long 0x70e09070, 0x00700000, 0x3e7c423e, 0x003e0000 -.long 0xb571c4b5, 0x00b50000, 0x66ccaa66, 0x00660000 -.long 0x4890d848, 0x00480000, 0x03060503, 0x00030000 -.long 0xf6f701f6, 0x00f60000, 0x0e1c120e, 0x000e0000 -.long 0x61c2a361, 0x00610000, 0x356a5f35, 0x00350000 -.long 0x57aef957, 0x00570000, 0xb969d0b9, 0x00b90000 -.long 0x86179186, 0x00860000, 0xc19958c1, 0x00c10000 -.long 0x1d3a271d, 0x001d0000, 0x9e27b99e, 0x009e0000 -.long 0xe1d938e1, 0x00e10000, 0xf8eb13f8, 0x00f80000 -.long 0x982bb398, 0x00980000, 0x11223311, 0x00110000 -.long 0x69d2bb69, 0x00690000, 0xd9a970d9, 0x00d90000 -.long 0x8e07898e, 0x008e0000, 0x9433a794, 0x00940000 -.long 0x9b2db69b, 0x009b0000, 0x1e3c221e, 0x001e0000 -.long 0x87159287, 0x00870000, 0xe9c920e9, 0x00e90000 -.long 0xce8749ce, 0x00ce0000, 0x55aaff55, 0x00550000 -.long 0x28507828, 0x00280000, 0xdfa57adf, 0x00df0000 -.long 0x8c038f8c, 0x008c0000, 0xa159f8a1, 0x00a10000 -.long 0x89098089, 0x00890000, 0x0d1a170d, 0x000d0000 -.long 0xbf65dabf, 0x00bf0000, 0xe6d731e6, 0x00e60000 -.long 0x4284c642, 0x00420000, 0x68d0b868, 0x00680000 -.long 0x4182c341, 0x00410000, 0x9929b099, 0x00990000 -.long 0x2d5a772d, 0x002d0000, 0x0f1e110f, 0x000f0000 -.long 0xb07bcbb0, 0x00b00000, 0x54a8fc54, 0x00540000 -.long 0xbb6dd6bb, 0x00bb0000, 0x162c3a16, 0x00160000 -.LtableE3: -.long 0xc6a56363 -.LtableEs3: -.long 0x63000000, 0xf8847c7c, 0x7c000000 -.long 0xee997777, 0x77000000, 0xf68d7b7b, 0x7b000000 -.long 0xff0df2f2, 0xf2000000, 0xd6bd6b6b, 0x6b000000 -.long 0xdeb16f6f, 0x6f000000, 0x9154c5c5, 0xc5000000 -.long 0x60503030, 0x30000000, 0x02030101, 0x01000000 -.long 0xcea96767, 0x67000000, 0x567d2b2b, 0x2b000000 -.long 0xe719fefe, 0xfe000000, 0xb562d7d7, 0xd7000000 -.long 0x4de6abab, 0xab000000, 0xec9a7676, 0x76000000 -.long 0x8f45caca, 0xca000000, 0x1f9d8282, 0x82000000 -.long 0x8940c9c9, 0xc9000000, 0xfa877d7d, 0x7d000000 -.long 0xef15fafa, 0xfa000000, 0xb2eb5959, 0x59000000 -.long 0x8ec94747, 0x47000000, 0xfb0bf0f0, 0xf0000000 -.long 0x41ecadad, 0xad000000, 0xb367d4d4, 0xd4000000 -.long 0x5ffda2a2, 0xa2000000, 0x45eaafaf, 0xaf000000 -.long 0x23bf9c9c, 0x9c000000, 0x53f7a4a4, 0xa4000000 -.long 0xe4967272, 0x72000000, 0x9b5bc0c0, 0xc0000000 -.long 0x75c2b7b7, 0xb7000000, 0xe11cfdfd, 0xfd000000 -.long 0x3dae9393, 0x93000000, 0x4c6a2626, 0x26000000 -.long 0x6c5a3636, 0x36000000, 0x7e413f3f, 0x3f000000 -.long 0xf502f7f7, 0xf7000000, 0x834fcccc, 0xcc000000 -.long 0x685c3434, 0x34000000, 0x51f4a5a5, 0xa5000000 -.long 0xd134e5e5, 0xe5000000, 0xf908f1f1, 0xf1000000 -.long 0xe2937171, 0x71000000, 0xab73d8d8, 0xd8000000 -.long 0x62533131, 0x31000000, 0x2a3f1515, 0x15000000 -.long 0x080c0404, 0x04000000, 0x9552c7c7, 0xc7000000 -.long 0x46652323, 0x23000000, 0x9d5ec3c3, 0xc3000000 -.long 0x30281818, 0x18000000, 0x37a19696, 0x96000000 -.long 0x0a0f0505, 0x05000000, 0x2fb59a9a, 0x9a000000 -.long 0x0e090707, 0x07000000, 0x24361212, 0x12000000 -.long 0x1b9b8080, 0x80000000, 0xdf3de2e2, 0xe2000000 -.long 0xcd26ebeb, 0xeb000000, 0x4e692727, 0x27000000 -.long 0x7fcdb2b2, 0xb2000000, 0xea9f7575, 0x75000000 -.long 0x121b0909, 0x09000000, 0x1d9e8383, 0x83000000 -.long 0x58742c2c, 0x2c000000, 0x342e1a1a, 0x1a000000 -.long 0x362d1b1b, 0x1b000000, 0xdcb26e6e, 0x6e000000 -.long 0xb4ee5a5a, 0x5a000000, 0x5bfba0a0, 0xa0000000 -.long 0xa4f65252, 0x52000000, 0x764d3b3b, 0x3b000000 -.long 0xb761d6d6, 0xd6000000, 0x7dceb3b3, 0xb3000000 -.long 0x527b2929, 0x29000000, 0xdd3ee3e3, 0xe3000000 -.long 0x5e712f2f, 0x2f000000, 0x13978484, 0x84000000 -.long 0xa6f55353, 0x53000000, 0xb968d1d1, 0xd1000000 -.long 0x00000000, 0x00000000, 0xc12ceded, 0xed000000 -.long 0x40602020, 0x20000000, 0xe31ffcfc, 0xfc000000 -.long 0x79c8b1b1, 0xb1000000, 0xb6ed5b5b, 0x5b000000 -.long 0xd4be6a6a, 0x6a000000, 0x8d46cbcb, 0xcb000000 -.long 0x67d9bebe, 0xbe000000, 0x724b3939, 0x39000000 -.long 0x94de4a4a, 0x4a000000, 0x98d44c4c, 0x4c000000 -.long 0xb0e85858, 0x58000000, 0x854acfcf, 0xcf000000 -.long 0xbb6bd0d0, 0xd0000000, 0xc52aefef, 0xef000000 -.long 0x4fe5aaaa, 0xaa000000, 0xed16fbfb, 0xfb000000 -.long 0x86c54343, 0x43000000, 0x9ad74d4d, 0x4d000000 -.long 0x66553333, 0x33000000, 0x11948585, 0x85000000 -.long 0x8acf4545, 0x45000000, 0xe910f9f9, 0xf9000000 -.long 0x04060202, 0x02000000, 0xfe817f7f, 0x7f000000 -.long 0xa0f05050, 0x50000000, 0x78443c3c, 0x3c000000 -.long 0x25ba9f9f, 0x9f000000, 0x4be3a8a8, 0xa8000000 -.long 0xa2f35151, 0x51000000, 0x5dfea3a3, 0xa3000000 -.long 0x80c04040, 0x40000000, 0x058a8f8f, 0x8f000000 -.long 0x3fad9292, 0x92000000, 0x21bc9d9d, 0x9d000000 -.long 0x70483838, 0x38000000, 0xf104f5f5, 0xf5000000 -.long 0x63dfbcbc, 0xbc000000, 0x77c1b6b6, 0xb6000000 -.long 0xaf75dada, 0xda000000, 0x42632121, 0x21000000 -.long 0x20301010, 0x10000000, 0xe51affff, 0xff000000 -.long 0xfd0ef3f3, 0xf3000000, 0xbf6dd2d2, 0xd2000000 -.long 0x814ccdcd, 0xcd000000, 0x18140c0c, 0x0c000000 -.long 0x26351313, 0x13000000, 0xc32fecec, 0xec000000 -.long 0xbee15f5f, 0x5f000000, 0x35a29797, 0x97000000 -.long 0x88cc4444, 0x44000000, 0x2e391717, 0x17000000 -.long 0x9357c4c4, 0xc4000000, 0x55f2a7a7, 0xa7000000 -.long 0xfc827e7e, 0x7e000000, 0x7a473d3d, 0x3d000000 -.long 0xc8ac6464, 0x64000000, 0xbae75d5d, 0x5d000000 -.long 0x322b1919, 0x19000000, 0xe6957373, 0x73000000 -.long 0xc0a06060, 0x60000000, 0x19988181, 0x81000000 -.long 0x9ed14f4f, 0x4f000000, 0xa37fdcdc, 0xdc000000 -.long 0x44662222, 0x22000000, 0x547e2a2a, 0x2a000000 -.long 0x3bab9090, 0x90000000, 0x0b838888, 0x88000000 -.long 0x8cca4646, 0x46000000, 0xc729eeee, 0xee000000 -.long 0x6bd3b8b8, 0xb8000000, 0x283c1414, 0x14000000 -.long 0xa779dede, 0xde000000, 0xbce25e5e, 0x5e000000 -.long 0x161d0b0b, 0x0b000000, 0xad76dbdb, 0xdb000000 -.long 0xdb3be0e0, 0xe0000000, 0x64563232, 0x32000000 -.long 0x744e3a3a, 0x3a000000, 0x141e0a0a, 0x0a000000 -.long 0x92db4949, 0x49000000, 0x0c0a0606, 0x06000000 -.long 0x486c2424, 0x24000000, 0xb8e45c5c, 0x5c000000 -.long 0x9f5dc2c2, 0xc2000000, 0xbd6ed3d3, 0xd3000000 -.long 0x43efacac, 0xac000000, 0xc4a66262, 0x62000000 -.long 0x39a89191, 0x91000000, 0x31a49595, 0x95000000 -.long 0xd337e4e4, 0xe4000000, 0xf28b7979, 0x79000000 -.long 0xd532e7e7, 0xe7000000, 0x8b43c8c8, 0xc8000000 -.long 0x6e593737, 0x37000000, 0xdab76d6d, 0x6d000000 -.long 0x018c8d8d, 0x8d000000, 0xb164d5d5, 0xd5000000 -.long 0x9cd24e4e, 0x4e000000, 0x49e0a9a9, 0xa9000000 -.long 0xd8b46c6c, 0x6c000000, 0xacfa5656, 0x56000000 -.long 0xf307f4f4, 0xf4000000, 0xcf25eaea, 0xea000000 -.long 0xcaaf6565, 0x65000000, 0xf48e7a7a, 0x7a000000 -.long 0x47e9aeae, 0xae000000, 0x10180808, 0x08000000 -.long 0x6fd5baba, 0xba000000, 0xf0887878, 0x78000000 -.long 0x4a6f2525, 0x25000000, 0x5c722e2e, 0x2e000000 -.long 0x38241c1c, 0x1c000000, 0x57f1a6a6, 0xa6000000 -.long 0x73c7b4b4, 0xb4000000, 0x9751c6c6, 0xc6000000 -.long 0xcb23e8e8, 0xe8000000, 0xa17cdddd, 0xdd000000 -.long 0xe89c7474, 0x74000000, 0x3e211f1f, 0x1f000000 -.long 0x96dd4b4b, 0x4b000000, 0x61dcbdbd, 0xbd000000 -.long 0x0d868b8b, 0x8b000000, 0x0f858a8a, 0x8a000000 -.long 0xe0907070, 0x70000000, 0x7c423e3e, 0x3e000000 -.long 0x71c4b5b5, 0xb5000000, 0xccaa6666, 0x66000000 -.long 0x90d84848, 0x48000000, 0x06050303, 0x03000000 -.long 0xf701f6f6, 0xf6000000, 0x1c120e0e, 0x0e000000 -.long 0xc2a36161, 0x61000000, 0x6a5f3535, 0x35000000 -.long 0xaef95757, 0x57000000, 0x69d0b9b9, 0xb9000000 -.long 0x17918686, 0x86000000, 0x9958c1c1, 0xc1000000 -.long 0x3a271d1d, 0x1d000000, 0x27b99e9e, 0x9e000000 -.long 0xd938e1e1, 0xe1000000, 0xeb13f8f8, 0xf8000000 -.long 0x2bb39898, 0x98000000, 0x22331111, 0x11000000 -.long 0xd2bb6969, 0x69000000, 0xa970d9d9, 0xd9000000 -.long 0x07898e8e, 0x8e000000, 0x33a79494, 0x94000000 -.long 0x2db69b9b, 0x9b000000, 0x3c221e1e, 0x1e000000 -.long 0x15928787, 0x87000000, 0xc920e9e9, 0xe9000000 -.long 0x8749cece, 0xce000000, 0xaaff5555, 0x55000000 -.long 0x50782828, 0x28000000, 0xa57adfdf, 0xdf000000 -.long 0x038f8c8c, 0x8c000000, 0x59f8a1a1, 0xa1000000 -.long 0x09808989, 0x89000000, 0x1a170d0d, 0x0d000000 -.long 0x65dabfbf, 0xbf000000, 0xd731e6e6, 0xe6000000 -.long 0x84c64242, 0x42000000, 0xd0b86868, 0x68000000 -.long 0x82c34141, 0x41000000, 0x29b09999, 0x99000000 -.long 0x5a772d2d, 0x2d000000, 0x1e110f0f, 0x0f000000 -.long 0x7bcbb0b0, 0xb0000000, 0xa8fc5454, 0x54000000 -.long 0x6dd6bbbb, 0xbb000000, 0x2c3a1616, 0x16000000 - -/* Decryption tables */ -.LtableD0: -.long 0x50a7f451 -.LtableDs0: -.long 0x00000052, 0x5365417e, 0x00000009 -.long 0xc3a4171a, 0x0000006a, 0x965e273a, 0x000000d5 -.long 0xcb6bab3b, 0x00000030, 0xf1459d1f, 0x00000036 -.long 0xab58faac, 0x000000a5, 0x9303e34b, 0x00000038 -.long 0x55fa3020, 0x000000bf, 0xf66d76ad, 0x00000040 -.long 0x9176cc88, 0x000000a3, 0x254c02f5, 0x0000009e -.long 0xfcd7e54f, 0x00000081, 0xd7cb2ac5, 0x000000f3 -.long 0x80443526, 0x000000d7, 0x8fa362b5, 0x000000fb -.long 0x495ab1de, 0x0000007c, 0x671bba25, 0x000000e3 -.long 0x980eea45, 0x00000039, 0xe1c0fe5d, 0x00000082 -.long 0x02752fc3, 0x0000009b, 0x12f04c81, 0x0000002f -.long 0xa397468d, 0x000000ff, 0xc6f9d36b, 0x00000087 -.long 0xe75f8f03, 0x00000034, 0x959c9215, 0x0000008e -.long 0xeb7a6dbf, 0x00000043, 0xda595295, 0x00000044 -.long 0x2d83bed4, 0x000000c4, 0xd3217458, 0x000000de -.long 0x2969e049, 0x000000e9, 0x44c8c98e, 0x000000cb -.long 0x6a89c275, 0x00000054, 0x78798ef4, 0x0000007b -.long 0x6b3e5899, 0x00000094, 0xdd71b927, 0x00000032 -.long 0xb64fe1be, 0x000000a6, 0x17ad88f0, 0x000000c2 -.long 0x66ac20c9, 0x00000023, 0xb43ace7d, 0x0000003d -.long 0x184adf63, 0x000000ee, 0x82311ae5, 0x0000004c -.long 0x60335197, 0x00000095, 0x457f5362, 0x0000000b -.long 0xe07764b1, 0x00000042, 0x84ae6bbb, 0x000000fa -.long 0x1ca081fe, 0x000000c3, 0x942b08f9, 0x0000004e -.long 0x58684870, 0x00000008, 0x19fd458f, 0x0000002e -.long 0x876cde94, 0x000000a1, 0xb7f87b52, 0x00000066 -.long 0x23d373ab, 0x00000028, 0xe2024b72, 0x000000d9 -.long 0x578f1fe3, 0x00000024, 0x2aab5566, 0x000000b2 -.long 0x0728ebb2, 0x00000076, 0x03c2b52f, 0x0000005b -.long 0x9a7bc586, 0x000000a2, 0xa50837d3, 0x00000049 -.long 0xf2872830, 0x0000006d, 0xb2a5bf23, 0x0000008b -.long 0xba6a0302, 0x000000d1, 0x5c8216ed, 0x00000025 -.long 0x2b1ccf8a, 0x00000072, 0x92b479a7, 0x000000f8 -.long 0xf0f207f3, 0x000000f6, 0xa1e2694e, 0x00000064 -.long 0xcdf4da65, 0x00000086, 0xd5be0506, 0x00000068 -.long 0x1f6234d1, 0x00000098, 0x8afea6c4, 0x00000016 -.long 0x9d532e34, 0x000000d4, 0xa055f3a2, 0x000000a4 -.long 0x32e18a05, 0x0000005c, 0x75ebf6a4, 0x000000cc -.long 0x39ec830b, 0x0000005d, 0xaaef6040, 0x00000065 -.long 0x069f715e, 0x000000b6, 0x51106ebd, 0x00000092 -.long 0xf98a213e, 0x0000006c, 0x3d06dd96, 0x00000070 -.long 0xae053edd, 0x00000048, 0x46bde64d, 0x00000050 -.long 0xb58d5491, 0x000000fd, 0x055dc471, 0x000000ed -.long 0x6fd40604, 0x000000b9, 0xff155060, 0x000000da -.long 0x24fb9819, 0x0000005e, 0x97e9bdd6, 0x00000015 -.long 0xcc434089, 0x00000046, 0x779ed967, 0x00000057 -.long 0xbd42e8b0, 0x000000a7, 0x888b8907, 0x0000008d -.long 0x385b19e7, 0x0000009d, 0xdbeec879, 0x00000084 -.long 0x470a7ca1, 0x00000090, 0xe90f427c, 0x000000d8 -.long 0xc91e84f8, 0x000000ab, 0x00000000, 0x00000000 -.long 0x83868009, 0x0000008c, 0x48ed2b32, 0x000000bc -.long 0xac70111e, 0x000000d3, 0x4e725a6c, 0x0000000a -.long 0xfbff0efd, 0x000000f7, 0x5638850f, 0x000000e4 -.long 0x1ed5ae3d, 0x00000058, 0x27392d36, 0x00000005 -.long 0x64d90f0a, 0x000000b8, 0x21a65c68, 0x000000b3 -.long 0xd1545b9b, 0x00000045, 0x3a2e3624, 0x00000006 -.long 0xb1670a0c, 0x000000d0, 0x0fe75793, 0x0000002c -.long 0xd296eeb4, 0x0000001e, 0x9e919b1b, 0x0000008f -.long 0x4fc5c080, 0x000000ca, 0xa220dc61, 0x0000003f -.long 0x694b775a, 0x0000000f, 0x161a121c, 0x00000002 -.long 0x0aba93e2, 0x000000c1, 0xe52aa0c0, 0x000000af -.long 0x43e0223c, 0x000000bd, 0x1d171b12, 0x00000003 -.long 0x0b0d090e, 0x00000001, 0xadc78bf2, 0x00000013 -.long 0xb9a8b62d, 0x0000008a, 0xc8a91e14, 0x0000006b -.long 0x8519f157, 0x0000003a, 0x4c0775af, 0x00000091 -.long 0xbbdd99ee, 0x00000011, 0xfd607fa3, 0x00000041 -.long 0x9f2601f7, 0x0000004f, 0xbcf5725c, 0x00000067 -.long 0xc53b6644, 0x000000dc, 0x347efb5b, 0x000000ea -.long 0x7629438b, 0x00000097, 0xdcc623cb, 0x000000f2 -.long 0x68fcedb6, 0x000000cf, 0x63f1e4b8, 0x000000ce -.long 0xcadc31d7, 0x000000f0, 0x10856342, 0x000000b4 -.long 0x40229713, 0x000000e6, 0x2011c684, 0x00000073 -.long 0x7d244a85, 0x00000096, 0xf83dbbd2, 0x000000ac -.long 0x1132f9ae, 0x00000074, 0x6da129c7, 0x00000022 -.long 0x4b2f9e1d, 0x000000e7, 0xf330b2dc, 0x000000ad -.long 0xec52860d, 0x00000035, 0xd0e3c177, 0x00000085 -.long 0x6c16b32b, 0x000000e2, 0x99b970a9, 0x000000f9 -.long 0xfa489411, 0x00000037, 0x2264e947, 0x000000e8 -.long 0xc48cfca8, 0x0000001c, 0x1a3ff0a0, 0x00000075 -.long 0xd82c7d56, 0x000000df, 0xef903322, 0x0000006e -.long 0xc74e4987, 0x00000047, 0xc1d138d9, 0x000000f1 -.long 0xfea2ca8c, 0x0000001a, 0x360bd498, 0x00000071 -.long 0xcf81f5a6, 0x0000001d, 0x28de7aa5, 0x00000029 -.long 0x268eb7da, 0x000000c5, 0xa4bfad3f, 0x00000089 -.long 0xe49d3a2c, 0x0000006f, 0x0d927850, 0x000000b7 -.long 0x9bcc5f6a, 0x00000062, 0x62467e54, 0x0000000e -.long 0xc2138df6, 0x000000aa, 0xe8b8d890, 0x00000018 -.long 0x5ef7392e, 0x000000be, 0xf5afc382, 0x0000001b -.long 0xbe805d9f, 0x000000fc, 0x7c93d069, 0x00000056 -.long 0xa92dd56f, 0x0000003e, 0xb31225cf, 0x0000004b -.long 0x3b99acc8, 0x000000c6, 0xa77d1810, 0x000000d2 -.long 0x6e639ce8, 0x00000079, 0x7bbb3bdb, 0x00000020 -.long 0x097826cd, 0x0000009a, 0xf418596e, 0x000000db -.long 0x01b79aec, 0x000000c0, 0xa89a4f83, 0x000000fe -.long 0x656e95e6, 0x00000078, 0x7ee6ffaa, 0x000000cd -.long 0x08cfbc21, 0x0000005a, 0xe6e815ef, 0x000000f4 -.long 0xd99be7ba, 0x0000001f, 0xce366f4a, 0x000000dd -.long 0xd4099fea, 0x000000a8, 0xd67cb029, 0x00000033 -.long 0xafb2a431, 0x00000088, 0x31233f2a, 0x00000007 -.long 0x3094a5c6, 0x000000c7, 0xc066a235, 0x00000031 -.long 0x37bc4e74, 0x000000b1, 0xa6ca82fc, 0x00000012 -.long 0xb0d090e0, 0x00000010, 0x15d8a733, 0x00000059 -.long 0x4a9804f1, 0x00000027, 0xf7daec41, 0x00000080 -.long 0x0e50cd7f, 0x000000ec, 0x2ff69117, 0x0000005f -.long 0x8dd64d76, 0x00000060, 0x4db0ef43, 0x00000051 -.long 0x544daacc, 0x0000007f, 0xdf0496e4, 0x000000a9 -.long 0xe3b5d19e, 0x00000019, 0x1b886a4c, 0x000000b5 -.long 0xb81f2cc1, 0x0000004a, 0x7f516546, 0x0000000d -.long 0x04ea5e9d, 0x0000002d, 0x5d358c01, 0x000000e5 -.long 0x737487fa, 0x0000007a, 0x2e410bfb, 0x0000009f -.long 0x5a1d67b3, 0x00000093, 0x52d2db92, 0x000000c9 -.long 0x335610e9, 0x0000009c, 0x1347d66d, 0x000000ef -.long 0x8c61d79a, 0x000000a0, 0x7a0ca137, 0x000000e0 -.long 0x8e14f859, 0x0000003b, 0x893c13eb, 0x0000004d -.long 0xee27a9ce, 0x000000ae, 0x35c961b7, 0x0000002a -.long 0xede51ce1, 0x000000f5, 0x3cb1477a, 0x000000b0 -.long 0x59dfd29c, 0x000000c8, 0x3f73f255, 0x000000eb -.long 0x79ce1418, 0x000000bb, 0xbf37c773, 0x0000003c -.long 0xeacdf753, 0x00000083, 0x5baafd5f, 0x00000053 -.long 0x146f3ddf, 0x00000099, 0x86db4478, 0x00000061 -.long 0x81f3afca, 0x00000017, 0x3ec468b9, 0x0000002b -.long 0x2c342438, 0x00000004, 0x5f40a3c2, 0x0000007e -.long 0x72c31d16, 0x000000ba, 0x0c25e2bc, 0x00000077 -.long 0x8b493c28, 0x000000d6, 0x41950dff, 0x00000026 -.long 0x7101a839, 0x000000e1, 0xdeb30c08, 0x00000069 -.long 0x9ce4b4d8, 0x00000014, 0x90c15664, 0x00000063 -.long 0x6184cb7b, 0x00000055, 0x70b632d5, 0x00000021 -.long 0x745c6c48, 0x0000000c, 0x4257b8d0, 0x0000007d -.LtableD1: -.long 0xa7f45150 -.LtableDs1: -.long 0x00005200, 0x65417e53, 0x00000900 -.long 0xa4171ac3, 0x00006a00, 0x5e273a96, 0x0000d500 -.long 0x6bab3bcb, 0x00003000, 0x459d1ff1, 0x00003600 -.long 0x58faacab, 0x0000a500, 0x03e34b93, 0x00003800 -.long 0xfa302055, 0x0000bf00, 0x6d76adf6, 0x00004000 -.long 0x76cc8891, 0x0000a300, 0x4c02f525, 0x00009e00 -.long 0xd7e54ffc, 0x00008100, 0xcb2ac5d7, 0x0000f300 -.long 0x44352680, 0x0000d700, 0xa362b58f, 0x0000fb00 -.long 0x5ab1de49, 0x00007c00, 0x1bba2567, 0x0000e300 -.long 0x0eea4598, 0x00003900, 0xc0fe5de1, 0x00008200 -.long 0x752fc302, 0x00009b00, 0xf04c8112, 0x00002f00 -.long 0x97468da3, 0x0000ff00, 0xf9d36bc6, 0x00008700 -.long 0x5f8f03e7, 0x00003400, 0x9c921595, 0x00008e00 -.long 0x7a6dbfeb, 0x00004300, 0x595295da, 0x00004400 -.long 0x83bed42d, 0x0000c400, 0x217458d3, 0x0000de00 -.long 0x69e04929, 0x0000e900, 0xc8c98e44, 0x0000cb00 -.long 0x89c2756a, 0x00005400, 0x798ef478, 0x00007b00 -.long 0x3e58996b, 0x00009400, 0x71b927dd, 0x00003200 -.long 0x4fe1beb6, 0x0000a600, 0xad88f017, 0x0000c200 -.long 0xac20c966, 0x00002300, 0x3ace7db4, 0x00003d00 -.long 0x4adf6318, 0x0000ee00, 0x311ae582, 0x00004c00 -.long 0x33519760, 0x00009500, 0x7f536245, 0x00000b00 -.long 0x7764b1e0, 0x00004200, 0xae6bbb84, 0x0000fa00 -.long 0xa081fe1c, 0x0000c300, 0x2b08f994, 0x00004e00 -.long 0x68487058, 0x00000800, 0xfd458f19, 0x00002e00 -.long 0x6cde9487, 0x0000a100, 0xf87b52b7, 0x00006600 -.long 0xd373ab23, 0x00002800, 0x024b72e2, 0x0000d900 -.long 0x8f1fe357, 0x00002400, 0xab55662a, 0x0000b200 -.long 0x28ebb207, 0x00007600, 0xc2b52f03, 0x00005b00 -.long 0x7bc5869a, 0x0000a200, 0x0837d3a5, 0x00004900 -.long 0x872830f2, 0x00006d00, 0xa5bf23b2, 0x00008b00 -.long 0x6a0302ba, 0x0000d100, 0x8216ed5c, 0x00002500 -.long 0x1ccf8a2b, 0x00007200, 0xb479a792, 0x0000f800 -.long 0xf207f3f0, 0x0000f600, 0xe2694ea1, 0x00006400 -.long 0xf4da65cd, 0x00008600, 0xbe0506d5, 0x00006800 -.long 0x6234d11f, 0x00009800, 0xfea6c48a, 0x00001600 -.long 0x532e349d, 0x0000d400, 0x55f3a2a0, 0x0000a400 -.long 0xe18a0532, 0x00005c00, 0xebf6a475, 0x0000cc00 -.long 0xec830b39, 0x00005d00, 0xef6040aa, 0x00006500 -.long 0x9f715e06, 0x0000b600, 0x106ebd51, 0x00009200 -.long 0x8a213ef9, 0x00006c00, 0x06dd963d, 0x00007000 -.long 0x053eddae, 0x00004800, 0xbde64d46, 0x00005000 -.long 0x8d5491b5, 0x0000fd00, 0x5dc47105, 0x0000ed00 -.long 0xd406046f, 0x0000b900, 0x155060ff, 0x0000da00 -.long 0xfb981924, 0x00005e00, 0xe9bdd697, 0x00001500 -.long 0x434089cc, 0x00004600, 0x9ed96777, 0x00005700 -.long 0x42e8b0bd, 0x0000a700, 0x8b890788, 0x00008d00 -.long 0x5b19e738, 0x00009d00, 0xeec879db, 0x00008400 -.long 0x0a7ca147, 0x00009000, 0x0f427ce9, 0x0000d800 -.long 0x1e84f8c9, 0x0000ab00, 0x00000000, 0x00000000 -.long 0x86800983, 0x00008c00, 0xed2b3248, 0x0000bc00 -.long 0x70111eac, 0x0000d300, 0x725a6c4e, 0x00000a00 -.long 0xff0efdfb, 0x0000f700, 0x38850f56, 0x0000e400 -.long 0xd5ae3d1e, 0x00005800, 0x392d3627, 0x00000500 -.long 0xd90f0a64, 0x0000b800, 0xa65c6821, 0x0000b300 -.long 0x545b9bd1, 0x00004500, 0x2e36243a, 0x00000600 -.long 0x670a0cb1, 0x0000d000, 0xe757930f, 0x00002c00 -.long 0x96eeb4d2, 0x00001e00, 0x919b1b9e, 0x00008f00 -.long 0xc5c0804f, 0x0000ca00, 0x20dc61a2, 0x00003f00 -.long 0x4b775a69, 0x00000f00, 0x1a121c16, 0x00000200 -.long 0xba93e20a, 0x0000c100, 0x2aa0c0e5, 0x0000af00 -.long 0xe0223c43, 0x0000bd00, 0x171b121d, 0x00000300 -.long 0x0d090e0b, 0x00000100, 0xc78bf2ad, 0x00001300 -.long 0xa8b62db9, 0x00008a00, 0xa91e14c8, 0x00006b00 -.long 0x19f15785, 0x00003a00, 0x0775af4c, 0x00009100 -.long 0xdd99eebb, 0x00001100, 0x607fa3fd, 0x00004100 -.long 0x2601f79f, 0x00004f00, 0xf5725cbc, 0x00006700 -.long 0x3b6644c5, 0x0000dc00, 0x7efb5b34, 0x0000ea00 -.long 0x29438b76, 0x00009700, 0xc623cbdc, 0x0000f200 -.long 0xfcedb668, 0x0000cf00, 0xf1e4b863, 0x0000ce00 -.long 0xdc31d7ca, 0x0000f000, 0x85634210, 0x0000b400 -.long 0x22971340, 0x0000e600, 0x11c68420, 0x00007300 -.long 0x244a857d, 0x00009600, 0x3dbbd2f8, 0x0000ac00 -.long 0x32f9ae11, 0x00007400, 0xa129c76d, 0x00002200 -.long 0x2f9e1d4b, 0x0000e700, 0x30b2dcf3, 0x0000ad00 -.long 0x52860dec, 0x00003500, 0xe3c177d0, 0x00008500 -.long 0x16b32b6c, 0x0000e200, 0xb970a999, 0x0000f900 -.long 0x489411fa, 0x00003700, 0x64e94722, 0x0000e800 -.long 0x8cfca8c4, 0x00001c00, 0x3ff0a01a, 0x00007500 -.long 0x2c7d56d8, 0x0000df00, 0x903322ef, 0x00006e00 -.long 0x4e4987c7, 0x00004700, 0xd138d9c1, 0x0000f100 -.long 0xa2ca8cfe, 0x00001a00, 0x0bd49836, 0x00007100 -.long 0x81f5a6cf, 0x00001d00, 0xde7aa528, 0x00002900 -.long 0x8eb7da26, 0x0000c500, 0xbfad3fa4, 0x00008900 -.long 0x9d3a2ce4, 0x00006f00, 0x9278500d, 0x0000b700 -.long 0xcc5f6a9b, 0x00006200, 0x467e5462, 0x00000e00 -.long 0x138df6c2, 0x0000aa00, 0xb8d890e8, 0x00001800 -.long 0xf7392e5e, 0x0000be00, 0xafc382f5, 0x00001b00 -.long 0x805d9fbe, 0x0000fc00, 0x93d0697c, 0x00005600 -.long 0x2dd56fa9, 0x00003e00, 0x1225cfb3, 0x00004b00 -.long 0x99acc83b, 0x0000c600, 0x7d1810a7, 0x0000d200 -.long 0x639ce86e, 0x00007900, 0xbb3bdb7b, 0x00002000 -.long 0x7826cd09, 0x00009a00, 0x18596ef4, 0x0000db00 -.long 0xb79aec01, 0x0000c000, 0x9a4f83a8, 0x0000fe00 -.long 0x6e95e665, 0x00007800, 0xe6ffaa7e, 0x0000cd00 -.long 0xcfbc2108, 0x00005a00, 0xe815efe6, 0x0000f400 -.long 0x9be7bad9, 0x00001f00, 0x366f4ace, 0x0000dd00 -.long 0x099fead4, 0x0000a800, 0x7cb029d6, 0x00003300 -.long 0xb2a431af, 0x00008800, 0x233f2a31, 0x00000700 -.long 0x94a5c630, 0x0000c700, 0x66a235c0, 0x00003100 -.long 0xbc4e7437, 0x0000b100, 0xca82fca6, 0x00001200 -.long 0xd090e0b0, 0x00001000, 0xd8a73315, 0x00005900 -.long 0x9804f14a, 0x00002700, 0xdaec41f7, 0x00008000 -.long 0x50cd7f0e, 0x0000ec00, 0xf691172f, 0x00005f00 -.long 0xd64d768d, 0x00006000, 0xb0ef434d, 0x00005100 -.long 0x4daacc54, 0x00007f00, 0x0496e4df, 0x0000a900 -.long 0xb5d19ee3, 0x00001900, 0x886a4c1b, 0x0000b500 -.long 0x1f2cc1b8, 0x00004a00, 0x5165467f, 0x00000d00 -.long 0xea5e9d04, 0x00002d00, 0x358c015d, 0x0000e500 -.long 0x7487fa73, 0x00007a00, 0x410bfb2e, 0x00009f00 -.long 0x1d67b35a, 0x00009300, 0xd2db9252, 0x0000c900 -.long 0x5610e933, 0x00009c00, 0x47d66d13, 0x0000ef00 -.long 0x61d79a8c, 0x0000a000, 0x0ca1377a, 0x0000e000 -.long 0x14f8598e, 0x00003b00, 0x3c13eb89, 0x00004d00 -.long 0x27a9ceee, 0x0000ae00, 0xc961b735, 0x00002a00 -.long 0xe51ce1ed, 0x0000f500, 0xb1477a3c, 0x0000b000 -.long 0xdfd29c59, 0x0000c800, 0x73f2553f, 0x0000eb00 -.long 0xce141879, 0x0000bb00, 0x37c773bf, 0x00003c00 -.long 0xcdf753ea, 0x00008300, 0xaafd5f5b, 0x00005300 -.long 0x6f3ddf14, 0x00009900, 0xdb447886, 0x00006100 -.long 0xf3afca81, 0x00001700, 0xc468b93e, 0x00002b00 -.long 0x3424382c, 0x00000400, 0x40a3c25f, 0x00007e00 -.long 0xc31d1672, 0x0000ba00, 0x25e2bc0c, 0x00007700 -.long 0x493c288b, 0x0000d600, 0x950dff41, 0x00002600 -.long 0x01a83971, 0x0000e100, 0xb30c08de, 0x00006900 -.long 0xe4b4d89c, 0x00001400, 0xc1566490, 0x00006300 -.long 0x84cb7b61, 0x00005500, 0xb632d570, 0x00002100 -.long 0x5c6c4874, 0x00000c00, 0x57b8d042, 0x00007d00 -.LtableD2: -.long 0xf45150a7 -.LtableDs2: -.long 0x00520000, 0x417e5365, 0x00090000 -.long 0x171ac3a4, 0x006a0000, 0x273a965e, 0x00d50000 -.long 0xab3bcb6b, 0x00300000, 0x9d1ff145, 0x00360000 -.long 0xfaacab58, 0x00a50000, 0xe34b9303, 0x00380000 -.long 0x302055fa, 0x00bf0000, 0x76adf66d, 0x00400000 -.long 0xcc889176, 0x00a30000, 0x02f5254c, 0x009e0000 -.long 0xe54ffcd7, 0x00810000, 0x2ac5d7cb, 0x00f30000 -.long 0x35268044, 0x00d70000, 0x62b58fa3, 0x00fb0000 -.long 0xb1de495a, 0x007c0000, 0xba25671b, 0x00e30000 -.long 0xea45980e, 0x00390000, 0xfe5de1c0, 0x00820000 -.long 0x2fc30275, 0x009b0000, 0x4c8112f0, 0x002f0000 -.long 0x468da397, 0x00ff0000, 0xd36bc6f9, 0x00870000 -.long 0x8f03e75f, 0x00340000, 0x9215959c, 0x008e0000 -.long 0x6dbfeb7a, 0x00430000, 0x5295da59, 0x00440000 -.long 0xbed42d83, 0x00c40000, 0x7458d321, 0x00de0000 -.long 0xe0492969, 0x00e90000, 0xc98e44c8, 0x00cb0000 -.long 0xc2756a89, 0x00540000, 0x8ef47879, 0x007b0000 -.long 0x58996b3e, 0x00940000, 0xb927dd71, 0x00320000 -.long 0xe1beb64f, 0x00a60000, 0x88f017ad, 0x00c20000 -.long 0x20c966ac, 0x00230000, 0xce7db43a, 0x003d0000 -.long 0xdf63184a, 0x00ee0000, 0x1ae58231, 0x004c0000 -.long 0x51976033, 0x00950000, 0x5362457f, 0x000b0000 -.long 0x64b1e077, 0x00420000, 0x6bbb84ae, 0x00fa0000 -.long 0x81fe1ca0, 0x00c30000, 0x08f9942b, 0x004e0000 -.long 0x48705868, 0x00080000, 0x458f19fd, 0x002e0000 -.long 0xde94876c, 0x00a10000, 0x7b52b7f8, 0x00660000 -.long 0x73ab23d3, 0x00280000, 0x4b72e202, 0x00d90000 -.long 0x1fe3578f, 0x00240000, 0x55662aab, 0x00b20000 -.long 0xebb20728, 0x00760000, 0xb52f03c2, 0x005b0000 -.long 0xc5869a7b, 0x00a20000, 0x37d3a508, 0x00490000 -.long 0x2830f287, 0x006d0000, 0xbf23b2a5, 0x008b0000 -.long 0x0302ba6a, 0x00d10000, 0x16ed5c82, 0x00250000 -.long 0xcf8a2b1c, 0x00720000, 0x79a792b4, 0x00f80000 -.long 0x07f3f0f2, 0x00f60000, 0x694ea1e2, 0x00640000 -.long 0xda65cdf4, 0x00860000, 0x0506d5be, 0x00680000 -.long 0x34d11f62, 0x00980000, 0xa6c48afe, 0x00160000 -.long 0x2e349d53, 0x00d40000, 0xf3a2a055, 0x00a40000 -.long 0x8a0532e1, 0x005c0000, 0xf6a475eb, 0x00cc0000 -.long 0x830b39ec, 0x005d0000, 0x6040aaef, 0x00650000 -.long 0x715e069f, 0x00b60000, 0x6ebd5110, 0x00920000 -.long 0x213ef98a, 0x006c0000, 0xdd963d06, 0x00700000 -.long 0x3eddae05, 0x00480000, 0xe64d46bd, 0x00500000 -.long 0x5491b58d, 0x00fd0000, 0xc471055d, 0x00ed0000 -.long 0x06046fd4, 0x00b90000, 0x5060ff15, 0x00da0000 -.long 0x981924fb, 0x005e0000, 0xbdd697e9, 0x00150000 -.long 0x4089cc43, 0x00460000, 0xd967779e, 0x00570000 -.long 0xe8b0bd42, 0x00a70000, 0x8907888b, 0x008d0000 -.long 0x19e7385b, 0x009d0000, 0xc879dbee, 0x00840000 -.long 0x7ca1470a, 0x00900000, 0x427ce90f, 0x00d80000 -.long 0x84f8c91e, 0x00ab0000, 0x00000000, 0x00000000 -.long 0x80098386, 0x008c0000, 0x2b3248ed, 0x00bc0000 -.long 0x111eac70, 0x00d30000, 0x5a6c4e72, 0x000a0000 -.long 0x0efdfbff, 0x00f70000, 0x850f5638, 0x00e40000 -.long 0xae3d1ed5, 0x00580000, 0x2d362739, 0x00050000 -.long 0x0f0a64d9, 0x00b80000, 0x5c6821a6, 0x00b30000 -.long 0x5b9bd154, 0x00450000, 0x36243a2e, 0x00060000 -.long 0x0a0cb167, 0x00d00000, 0x57930fe7, 0x002c0000 -.long 0xeeb4d296, 0x001e0000, 0x9b1b9e91, 0x008f0000 -.long 0xc0804fc5, 0x00ca0000, 0xdc61a220, 0x003f0000 -.long 0x775a694b, 0x000f0000, 0x121c161a, 0x00020000 -.long 0x93e20aba, 0x00c10000, 0xa0c0e52a, 0x00af0000 -.long 0x223c43e0, 0x00bd0000, 0x1b121d17, 0x00030000 -.long 0x090e0b0d, 0x00010000, 0x8bf2adc7, 0x00130000 -.long 0xb62db9a8, 0x008a0000, 0x1e14c8a9, 0x006b0000 -.long 0xf1578519, 0x003a0000, 0x75af4c07, 0x00910000 -.long 0x99eebbdd, 0x00110000, 0x7fa3fd60, 0x00410000 -.long 0x01f79f26, 0x004f0000, 0x725cbcf5, 0x00670000 -.long 0x6644c53b, 0x00dc0000, 0xfb5b347e, 0x00ea0000 -.long 0x438b7629, 0x00970000, 0x23cbdcc6, 0x00f20000 -.long 0xedb668fc, 0x00cf0000, 0xe4b863f1, 0x00ce0000 -.long 0x31d7cadc, 0x00f00000, 0x63421085, 0x00b40000 -.long 0x97134022, 0x00e60000, 0xc6842011, 0x00730000 -.long 0x4a857d24, 0x00960000, 0xbbd2f83d, 0x00ac0000 -.long 0xf9ae1132, 0x00740000, 0x29c76da1, 0x00220000 -.long 0x9e1d4b2f, 0x00e70000, 0xb2dcf330, 0x00ad0000 -.long 0x860dec52, 0x00350000, 0xc177d0e3, 0x00850000 -.long 0xb32b6c16, 0x00e20000, 0x70a999b9, 0x00f90000 -.long 0x9411fa48, 0x00370000, 0xe9472264, 0x00e80000 -.long 0xfca8c48c, 0x001c0000, 0xf0a01a3f, 0x00750000 -.long 0x7d56d82c, 0x00df0000, 0x3322ef90, 0x006e0000 -.long 0x4987c74e, 0x00470000, 0x38d9c1d1, 0x00f10000 -.long 0xca8cfea2, 0x001a0000, 0xd498360b, 0x00710000 -.long 0xf5a6cf81, 0x001d0000, 0x7aa528de, 0x00290000 -.long 0xb7da268e, 0x00c50000, 0xad3fa4bf, 0x00890000 -.long 0x3a2ce49d, 0x006f0000, 0x78500d92, 0x00b70000 -.long 0x5f6a9bcc, 0x00620000, 0x7e546246, 0x000e0000 -.long 0x8df6c213, 0x00aa0000, 0xd890e8b8, 0x00180000 -.long 0x392e5ef7, 0x00be0000, 0xc382f5af, 0x001b0000 -.long 0x5d9fbe80, 0x00fc0000, 0xd0697c93, 0x00560000 -.long 0xd56fa92d, 0x003e0000, 0x25cfb312, 0x004b0000 -.long 0xacc83b99, 0x00c60000, 0x1810a77d, 0x00d20000 -.long 0x9ce86e63, 0x00790000, 0x3bdb7bbb, 0x00200000 -.long 0x26cd0978, 0x009a0000, 0x596ef418, 0x00db0000 -.long 0x9aec01b7, 0x00c00000, 0x4f83a89a, 0x00fe0000 -.long 0x95e6656e, 0x00780000, 0xffaa7ee6, 0x00cd0000 -.long 0xbc2108cf, 0x005a0000, 0x15efe6e8, 0x00f40000 -.long 0xe7bad99b, 0x001f0000, 0x6f4ace36, 0x00dd0000 -.long 0x9fead409, 0x00a80000, 0xb029d67c, 0x00330000 -.long 0xa431afb2, 0x00880000, 0x3f2a3123, 0x00070000 -.long 0xa5c63094, 0x00c70000, 0xa235c066, 0x00310000 -.long 0x4e7437bc, 0x00b10000, 0x82fca6ca, 0x00120000 -.long 0x90e0b0d0, 0x00100000, 0xa73315d8, 0x00590000 -.long 0x04f14a98, 0x00270000, 0xec41f7da, 0x00800000 -.long 0xcd7f0e50, 0x00ec0000, 0x91172ff6, 0x005f0000 -.long 0x4d768dd6, 0x00600000, 0xef434db0, 0x00510000 -.long 0xaacc544d, 0x007f0000, 0x96e4df04, 0x00a90000 -.long 0xd19ee3b5, 0x00190000, 0x6a4c1b88, 0x00b50000 -.long 0x2cc1b81f, 0x004a0000, 0x65467f51, 0x000d0000 -.long 0x5e9d04ea, 0x002d0000, 0x8c015d35, 0x00e50000 -.long 0x87fa7374, 0x007a0000, 0x0bfb2e41, 0x009f0000 -.long 0x67b35a1d, 0x00930000, 0xdb9252d2, 0x00c90000 -.long 0x10e93356, 0x009c0000, 0xd66d1347, 0x00ef0000 -.long 0xd79a8c61, 0x00a00000, 0xa1377a0c, 0x00e00000 -.long 0xf8598e14, 0x003b0000, 0x13eb893c, 0x004d0000 -.long 0xa9ceee27, 0x00ae0000, 0x61b735c9, 0x002a0000 -.long 0x1ce1ede5, 0x00f50000, 0x477a3cb1, 0x00b00000 -.long 0xd29c59df, 0x00c80000, 0xf2553f73, 0x00eb0000 -.long 0x141879ce, 0x00bb0000, 0xc773bf37, 0x003c0000 -.long 0xf753eacd, 0x00830000, 0xfd5f5baa, 0x00530000 -.long 0x3ddf146f, 0x00990000, 0x447886db, 0x00610000 -.long 0xafca81f3, 0x00170000, 0x68b93ec4, 0x002b0000 -.long 0x24382c34, 0x00040000, 0xa3c25f40, 0x007e0000 -.long 0x1d1672c3, 0x00ba0000, 0xe2bc0c25, 0x00770000 -.long 0x3c288b49, 0x00d60000, 0x0dff4195, 0x00260000 -.long 0xa8397101, 0x00e10000, 0x0c08deb3, 0x00690000 -.long 0xb4d89ce4, 0x00140000, 0x566490c1, 0x00630000 -.long 0xcb7b6184, 0x00550000, 0x32d570b6, 0x00210000 -.long 0x6c48745c, 0x000c0000, 0xb8d04257, 0x007d0000 -.LtableD3: -.long 0x5150a7f4 -.LtableDs3: -.long 0x52000000, 0x7e536541, 0x09000000 -.long 0x1ac3a417, 0x6a000000, 0x3a965e27, 0xd5000000 -.long 0x3bcb6bab, 0x30000000, 0x1ff1459d, 0x36000000 -.long 0xacab58fa, 0xa5000000, 0x4b9303e3, 0x38000000 -.long 0x2055fa30, 0xbf000000, 0xadf66d76, 0x40000000 -.long 0x889176cc, 0xa3000000, 0xf5254c02, 0x9e000000 -.long 0x4ffcd7e5, 0x81000000, 0xc5d7cb2a, 0xf3000000 -.long 0x26804435, 0xd7000000, 0xb58fa362, 0xfb000000 -.long 0xde495ab1, 0x7c000000, 0x25671bba, 0xe3000000 -.long 0x45980eea, 0x39000000, 0x5de1c0fe, 0x82000000 -.long 0xc302752f, 0x9b000000, 0x8112f04c, 0x2f000000 -.long 0x8da39746, 0xff000000, 0x6bc6f9d3, 0x87000000 -.long 0x03e75f8f, 0x34000000, 0x15959c92, 0x8e000000 -.long 0xbfeb7a6d, 0x43000000, 0x95da5952, 0x44000000 -.long 0xd42d83be, 0xc4000000, 0x58d32174, 0xde000000 -.long 0x492969e0, 0xe9000000, 0x8e44c8c9, 0xcb000000 -.long 0x756a89c2, 0x54000000, 0xf478798e, 0x7b000000 -.long 0x996b3e58, 0x94000000, 0x27dd71b9, 0x32000000 -.long 0xbeb64fe1, 0xa6000000, 0xf017ad88, 0xc2000000 -.long 0xc966ac20, 0x23000000, 0x7db43ace, 0x3d000000 -.long 0x63184adf, 0xee000000, 0xe582311a, 0x4c000000 -.long 0x97603351, 0x95000000, 0x62457f53, 0x0b000000 -.long 0xb1e07764, 0x42000000, 0xbb84ae6b, 0xfa000000 -.long 0xfe1ca081, 0xc3000000, 0xf9942b08, 0x4e000000 -.long 0x70586848, 0x08000000, 0x8f19fd45, 0x2e000000 -.long 0x94876cde, 0xa1000000, 0x52b7f87b, 0x66000000 -.long 0xab23d373, 0x28000000, 0x72e2024b, 0xd9000000 -.long 0xe3578f1f, 0x24000000, 0x662aab55, 0xb2000000 -.long 0xb20728eb, 0x76000000, 0x2f03c2b5, 0x5b000000 -.long 0x869a7bc5, 0xa2000000, 0xd3a50837, 0x49000000 -.long 0x30f28728, 0x6d000000, 0x23b2a5bf, 0x8b000000 -.long 0x02ba6a03, 0xd1000000, 0xed5c8216, 0x25000000 -.long 0x8a2b1ccf, 0x72000000, 0xa792b479, 0xf8000000 -.long 0xf3f0f207, 0xf6000000, 0x4ea1e269, 0x64000000 -.long 0x65cdf4da, 0x86000000, 0x06d5be05, 0x68000000 -.long 0xd11f6234, 0x98000000, 0xc48afea6, 0x16000000 -.long 0x349d532e, 0xd4000000, 0xa2a055f3, 0xa4000000 -.long 0x0532e18a, 0x5c000000, 0xa475ebf6, 0xcc000000 -.long 0x0b39ec83, 0x5d000000, 0x40aaef60, 0x65000000 -.long 0x5e069f71, 0xb6000000, 0xbd51106e, 0x92000000 -.long 0x3ef98a21, 0x6c000000, 0x963d06dd, 0x70000000 -.long 0xddae053e, 0x48000000, 0x4d46bde6, 0x50000000 -.long 0x91b58d54, 0xfd000000, 0x71055dc4, 0xed000000 -.long 0x046fd406, 0xb9000000, 0x60ff1550, 0xda000000 -.long 0x1924fb98, 0x5e000000, 0xd697e9bd, 0x15000000 -.long 0x89cc4340, 0x46000000, 0x67779ed9, 0x57000000 -.long 0xb0bd42e8, 0xa7000000, 0x07888b89, 0x8d000000 -.long 0xe7385b19, 0x9d000000, 0x79dbeec8, 0x84000000 -.long 0xa1470a7c, 0x90000000, 0x7ce90f42, 0xd8000000 -.long 0xf8c91e84, 0xab000000, 0x00000000, 0x00000000 -.long 0x09838680, 0x8c000000, 0x3248ed2b, 0xbc000000 -.long 0x1eac7011, 0xd3000000, 0x6c4e725a, 0x0a000000 -.long 0xfdfbff0e, 0xf7000000, 0x0f563885, 0xe4000000 -.long 0x3d1ed5ae, 0x58000000, 0x3627392d, 0x05000000 -.long 0x0a64d90f, 0xb8000000, 0x6821a65c, 0xb3000000 -.long 0x9bd1545b, 0x45000000, 0x243a2e36, 0x06000000 -.long 0x0cb1670a, 0xd0000000, 0x930fe757, 0x2c000000 -.long 0xb4d296ee, 0x1e000000, 0x1b9e919b, 0x8f000000 -.long 0x804fc5c0, 0xca000000, 0x61a220dc, 0x3f000000 -.long 0x5a694b77, 0x0f000000, 0x1c161a12, 0x02000000 -.long 0xe20aba93, 0xc1000000, 0xc0e52aa0, 0xaf000000 -.long 0x3c43e022, 0xbd000000, 0x121d171b, 0x03000000 -.long 0x0e0b0d09, 0x01000000, 0xf2adc78b, 0x13000000 -.long 0x2db9a8b6, 0x8a000000, 0x14c8a91e, 0x6b000000 -.long 0x578519f1, 0x3a000000, 0xaf4c0775, 0x91000000 -.long 0xeebbdd99, 0x11000000, 0xa3fd607f, 0x41000000 -.long 0xf79f2601, 0x4f000000, 0x5cbcf572, 0x67000000 -.long 0x44c53b66, 0xdc000000, 0x5b347efb, 0xea000000 -.long 0x8b762943, 0x97000000, 0xcbdcc623, 0xf2000000 -.long 0xb668fced, 0xcf000000, 0xb863f1e4, 0xce000000 -.long 0xd7cadc31, 0xf0000000, 0x42108563, 0xb4000000 -.long 0x13402297, 0xe6000000, 0x842011c6, 0x73000000 -.long 0x857d244a, 0x96000000, 0xd2f83dbb, 0xac000000 -.long 0xae1132f9, 0x74000000, 0xc76da129, 0x22000000 -.long 0x1d4b2f9e, 0xe7000000, 0xdcf330b2, 0xad000000 -.long 0x0dec5286, 0x35000000, 0x77d0e3c1, 0x85000000 -.long 0x2b6c16b3, 0xe2000000, 0xa999b970, 0xf9000000 -.long 0x11fa4894, 0x37000000, 0x472264e9, 0xe8000000 -.long 0xa8c48cfc, 0x1c000000, 0xa01a3ff0, 0x75000000 -.long 0x56d82c7d, 0xdf000000, 0x22ef9033, 0x6e000000 -.long 0x87c74e49, 0x47000000, 0xd9c1d138, 0xf1000000 -.long 0x8cfea2ca, 0x1a000000, 0x98360bd4, 0x71000000 -.long 0xa6cf81f5, 0x1d000000, 0xa528de7a, 0x29000000 -.long 0xda268eb7, 0xc5000000, 0x3fa4bfad, 0x89000000 -.long 0x2ce49d3a, 0x6f000000, 0x500d9278, 0xb7000000 -.long 0x6a9bcc5f, 0x62000000, 0x5462467e, 0x0e000000 -.long 0xf6c2138d, 0xaa000000, 0x90e8b8d8, 0x18000000 -.long 0x2e5ef739, 0xbe000000, 0x82f5afc3, 0x1b000000 -.long 0x9fbe805d, 0xfc000000, 0x697c93d0, 0x56000000 -.long 0x6fa92dd5, 0x3e000000, 0xcfb31225, 0x4b000000 -.long 0xc83b99ac, 0xc6000000, 0x10a77d18, 0xd2000000 -.long 0xe86e639c, 0x79000000, 0xdb7bbb3b, 0x20000000 -.long 0xcd097826, 0x9a000000, 0x6ef41859, 0xdb000000 -.long 0xec01b79a, 0xc0000000, 0x83a89a4f, 0xfe000000 -.long 0xe6656e95, 0x78000000, 0xaa7ee6ff, 0xcd000000 -.long 0x2108cfbc, 0x5a000000, 0xefe6e815, 0xf4000000 -.long 0xbad99be7, 0x1f000000, 0x4ace366f, 0xdd000000 -.long 0xead4099f, 0xa8000000, 0x29d67cb0, 0x33000000 -.long 0x31afb2a4, 0x88000000, 0x2a31233f, 0x07000000 -.long 0xc63094a5, 0xc7000000, 0x35c066a2, 0x31000000 -.long 0x7437bc4e, 0xb1000000, 0xfca6ca82, 0x12000000 -.long 0xe0b0d090, 0x10000000, 0x3315d8a7, 0x59000000 -.long 0xf14a9804, 0x27000000, 0x41f7daec, 0x80000000 -.long 0x7f0e50cd, 0xec000000, 0x172ff691, 0x5f000000 -.long 0x768dd64d, 0x60000000, 0x434db0ef, 0x51000000 -.long 0xcc544daa, 0x7f000000, 0xe4df0496, 0xa9000000 -.long 0x9ee3b5d1, 0x19000000, 0x4c1b886a, 0xb5000000 -.long 0xc1b81f2c, 0x4a000000, 0x467f5165, 0x0d000000 -.long 0x9d04ea5e, 0x2d000000, 0x015d358c, 0xe5000000 -.long 0xfa737487, 0x7a000000, 0xfb2e410b, 0x9f000000 -.long 0xb35a1d67, 0x93000000, 0x9252d2db, 0xc9000000 -.long 0xe9335610, 0x9c000000, 0x6d1347d6, 0xef000000 -.long 0x9a8c61d7, 0xa0000000, 0x377a0ca1, 0xe0000000 -.long 0x598e14f8, 0x3b000000, 0xeb893c13, 0x4d000000 -.long 0xceee27a9, 0xae000000, 0xb735c961, 0x2a000000 -.long 0xe1ede51c, 0xf5000000, 0x7a3cb147, 0xb0000000 -.long 0x9c59dfd2, 0xc8000000, 0x553f73f2, 0xeb000000 -.long 0x1879ce14, 0xbb000000, 0x73bf37c7, 0x3c000000 -.long 0x53eacdf7, 0x83000000, 0x5f5baafd, 0x53000000 -.long 0xdf146f3d, 0x99000000, 0x7886db44, 0x61000000 -.long 0xca81f3af, 0x17000000, 0xb93ec468, 0x2b000000 -.long 0x382c3424, 0x04000000, 0xc25f40a3, 0x7e000000 -.long 0x1672c31d, 0xba000000, 0xbc0c25e2, 0x77000000 -.long 0x288b493c, 0xd6000000, 0xff41950d, 0x26000000 -.long 0x397101a8, 0xe1000000, 0x08deb30c, 0x69000000 -.long 0xd89ce4b4, 0x14000000, 0x6490c156, 0x63000000 -.long 0x7b6184cb, 0x55000000, 0xd570b632, 0x21000000 -.long 0x48745c6c, 0x0c000000, 0xd04257b8, 0x7d000000 - #endif /*USE_AES*/ #endif /*__x86_64*/ diff --git a/cipher/rijndael-arm.S b/cipher/rijndael-arm.S index c385e67..694369d 100644 --- a/cipher/rijndael-arm.S +++ b/cipher/rijndael-arm.S @@ -28,19 +28,6 @@ .syntax unified .arm -#ifdef __PIC__ -# define GET_DATA_POINTER(reg, name, rtmp) \ - ldr reg, 1f; \ - ldr rtmp, 2f; \ - b 3f; \ - 1: .word _GLOBAL_OFFSET_TABLE_-(3f+8); \ - 2: .word name(GOT); \ - 3: add reg, pc, reg; \ - ldr reg, [reg, rtmp]; -#else -# define GET_DATA_POINTER(reg, name, rtmp) ldr reg, =name -#endif - /* register macros */ #define CTX %r0 #define RTAB %lr @@ -98,55 +85,55 @@ #define do_encround(next_r, ra, rb, rc, rd, rna, rnb, rnc, rnd, preload_key) \ ldr rnb, [CTX, #(((next_r) * 16) + 1 * 4)]; \ \ - and RT0, RMASK, ra, lsl#3; \ + and RT0, RMASK, ra, lsl#2; \ ldr rnc, [CTX, #(((next_r) * 16) + 2 * 4)]; \ - and RT1, RMASK, ra, lsr#(8 - 3); \ + and RT1, RMASK, ra, lsr#(8 - 2); \ ldr rnd, [CTX, #(((next_r) * 16) + 3 * 4)]; \ - and RT2, RMASK, ra, lsr#(16 - 3); \ + and RT2, RMASK, ra, lsr#(16 - 2); \ ldr RT0, [RTAB, RT0]; \ - and ra, RMASK, ra, lsr#(24 - 3); \ + and ra, RMASK, ra, lsr#(24 - 2); \ \ ldr RT1, [RTAB, RT1]; \ eor rna, rna, RT0; \ ldr RT2, [RTAB, RT2]; \ - and RT0, RMASK, rd, lsl#3; \ + and RT0, RMASK, rd, lsl#2; \ ldr ra, [RTAB, ra]; \ \ eor rnd, rnd, RT1, ror #24; \ - and RT1, RMASK, rd, lsr#(8 - 3); \ + and RT1, RMASK, rd, lsr#(8 - 2); \ eor rnc, rnc, RT2, ror #16; \ - and RT2, RMASK, rd, lsr#(16 - 3); \ + and RT2, RMASK, rd, lsr#(16 - 2); \ eor rnb, rnb, ra, ror #8; \ ldr RT0, [RTAB, RT0]; \ - and rd, RMASK, rd, lsr#(24 - 3); \ + and rd, RMASK, rd, lsr#(24 - 2); \ \ ldr RT1, [RTAB, RT1]; \ eor rnd, rnd, RT0; \ ldr RT2, [RTAB, RT2]; \ - and RT0, RMASK, rc, lsl#3; \ + and RT0, RMASK, rc, lsl#2; \ ldr rd, [RTAB, rd]; \ \ eor rnc, rnc, RT1, ror #24; \ - and RT1, RMASK, rc, lsr#(8 - 3); \ + and RT1, RMASK, rc, lsr#(8 - 2); \ eor rnb, rnb, RT2, ror #16; \ - and RT2, RMASK, rc, lsr#(16 - 3); \ + and RT2, RMASK, rc, lsr#(16 - 2); \ eor rna, rna, rd, ror #8; \ ldr RT0, [RTAB, RT0]; \ - and rc, RMASK, rc, lsr#(24 - 3); \ + and rc, RMASK, rc, lsr#(24 - 2); \ \ ldr RT1, [RTAB, RT1]; \ eor rnc, rnc, RT0; \ ldr RT2, [RTAB, RT2]; \ - and RT0, RMASK, rb, lsl#3; \ + and RT0, RMASK, rb, lsl#2; \ ldr rc, [RTAB, rc]; \ \ eor rnb, rnb, RT1, ror #24; \ - and RT1, RMASK, rb, lsr#(8 - 3); \ + and RT1, RMASK, rb, lsr#(8 - 2); \ eor rna, rna, RT2, ror #16; \ - and RT2, RMASK, rb, lsr#(16 - 3); \ + and RT2, RMASK, rb, lsr#(16 - 2); \ eor rnd, rnd, rc, ror #8; \ ldr RT0, [RTAB, RT0]; \ - and rb, RMASK, rb, lsr#(24 - 3); \ + and rb, RMASK, rb, lsr#(24 - 2); \ \ ldr RT1, [RTAB, RT1]; \ eor rnb, rnb, RT0; \ @@ -159,51 +146,51 @@ eor rnc, rnc, rb, ror #8; #define do_lastencround(ra, rb, rc, rd, rna, rnb, rnc, rnd) \ - and RT0, RMASK, ra, lsl#3; \ - and RT1, RMASK, ra, lsr#(8 - 3); \ - and RT2, RMASK, ra, lsr#(16 - 3); \ - ldr rna, [RTAB, RT0]; \ - and ra, RMASK, ra, lsr#(24 - 3); \ - ldr rnd, [RTAB, RT1]; \ - and RT0, RMASK, rd, lsl#3; \ - ldr rnc, [RTAB, RT2]; \ + and RT0, RMASK, ra, lsl#2; \ + and RT1, RMASK, ra, lsr#(8 - 2); \ + and RT2, RMASK, ra, lsr#(16 - 2); \ + ldrb rna, [RTAB, RT0]; \ + and ra, RMASK, ra, lsr#(24 - 2); \ + ldrb rnd, [RTAB, RT1]; \ + and RT0, RMASK, rd, lsl#2; \ + ldrb rnc, [RTAB, RT2]; \ mov rnd, rnd, ror #24; \ - ldr rnb, [RTAB, ra]; \ - and RT1, RMASK, rd, lsr#(8 - 3); \ + ldrb rnb, [RTAB, ra]; \ + and RT1, RMASK, rd, lsr#(8 - 2); \ mov rnc, rnc, ror #16; \ - and RT2, RMASK, rd, lsr#(16 - 3); \ + and RT2, RMASK, rd, lsr#(16 - 2); \ mov rnb, rnb, ror #8; \ - ldr RT0, [RTAB, RT0]; \ - and rd, RMASK, rd, lsr#(24 - 3); \ - ldr RT1, [RTAB, RT1]; \ + ldrb RT0, [RTAB, RT0]; \ + and rd, RMASK, rd, lsr#(24 - 2); \ + ldrb RT1, [RTAB, RT1]; \ \ orr rnd, rnd, RT0; \ - ldr RT2, [RTAB, RT2]; \ - and RT0, RMASK, rc, lsl#3; \ - ldr rd, [RTAB, rd]; \ + ldrb RT2, [RTAB, RT2]; \ + and RT0, RMASK, rc, lsl#2; \ + ldrb rd, [RTAB, rd]; \ orr rnc, rnc, RT1, ror #24; \ - and RT1, RMASK, rc, lsr#(8 - 3); \ + and RT1, RMASK, rc, lsr#(8 - 2); \ orr rnb, rnb, RT2, ror #16; \ - and RT2, RMASK, rc, lsr#(16 - 3); \ + and RT2, RMASK, rc, lsr#(16 - 2); \ orr rna, rna, rd, ror #8; \ - ldr RT0, [RTAB, RT0]; \ - and rc, RMASK, rc, lsr#(24 - 3); \ - ldr RT1, [RTAB, RT1]; \ + ldrb RT0, [RTAB, RT0]; \ + and rc, RMASK, rc, lsr#(24 - 2); \ + ldrb RT1, [RTAB, RT1]; \ \ orr rnc, rnc, RT0; \ - ldr RT2, [RTAB, RT2]; \ - and RT0, RMASK, rb, lsl#3; \ - ldr rc, [RTAB, rc]; \ + ldrb RT2, [RTAB, RT2]; \ + and RT0, RMASK, rb, lsl#2; \ + ldrb rc, [RTAB, rc]; \ orr rnb, rnb, RT1, ror #24; \ - and RT1, RMASK, rb, lsr#(8 - 3); \ + and RT1, RMASK, rb, lsr#(8 - 2); \ orr rna, rna, RT2, ror #16; \ - ldr RT0, [RTAB, RT0]; \ - and RT2, RMASK, rb, lsr#(16 - 3); \ - ldr RT1, [RTAB, RT1]; \ + ldrb RT0, [RTAB, RT0]; \ + and RT2, RMASK, rb, lsr#(16 - 2); \ + ldrb RT1, [RTAB, RT1]; \ orr rnd, rnd, rc, ror #8; \ - ldr RT2, [RTAB, RT2]; \ - and rb, RMASK, rb, lsr#(24 - 3); \ - ldr rb, [RTAB, rb]; \ + ldrb RT2, [RTAB, RT2]; \ + and rb, RMASK, rb, lsr#(24 - 2); \ + ldrb rb, [RTAB, rb]; \ \ orr rnb, rnb, RT0; \ orr rna, rna, RT1, ror #24; \ @@ -219,7 +206,7 @@ #define lastencround(round, ra, rb, rc, rd, rna, rnb, rnc, rnd) \ add CTX, #(((round) + 1) * 16); \ - add RTAB, #4; \ + add RTAB, #1; \ do_lastencround(ra, rb, rc, rd, rna, rnb, rnc, rnd); \ addroundkey(rna, rnb, rnc, rnd, ra, rb, rc, rd, dummy); @@ -233,6 +220,7 @@ _gcry_aes_arm_encrypt_block: * %r1: dst * %r2: src * %r3: number of rounds.. 10, 12 or 14 + * %st+0: encryption table */ push {%r4-%r11, %ip, %lr}; @@ -260,14 +248,13 @@ _gcry_aes_arm_encrypt_block: rev RD, RD; #endif 2: + ldr RTAB, [%sp, #40]; sub %sp, #16; - GET_DATA_POINTER(RTAB, .LtableE0, RMASK); - str %r1, [%sp, #4]; /* dst */ mov RMASK, #0xff; str %r3, [%sp, #8]; /* nrounds */ - mov RMASK, RMASK, lsl#3; /* byte mask */ + mov RMASK, RMASK, lsl#2; /* byte mask */ firstencround(0, RA, RB, RC, RD, RNA, RNB, RNC, RND); encround(1, RNA, RNB, RNC, RND, RA, RB, RC, RD, preload_first_key); @@ -355,55 +342,55 @@ _gcry_aes_arm_encrypt_block: #define do_decround(next_r, ra, rb, rc, rd, rna, rnb, rnc, rnd, preload_key) \ ldr rnb, [CTX, #(((next_r) * 16) + 1 * 4)]; \ \ - and RT0, RMASK, ra, lsl#3; \ + and RT0, RMASK, ra, lsl#2; \ ldr rnc, [CTX, #(((next_r) * 16) + 2 * 4)]; \ - and RT1, RMASK, ra, lsr#(8 - 3); \ + and RT1, RMASK, ra, lsr#(8 - 2); \ ldr rnd, [CTX, #(((next_r) * 16) + 3 * 4)]; \ - and RT2, RMASK, ra, lsr#(16 - 3); \ + and RT2, RMASK, ra, lsr#(16 - 2); \ ldr RT0, [RTAB, RT0]; \ - and ra, RMASK, ra, lsr#(24 - 3); \ + and ra, RMASK, ra, lsr#(24 - 2); \ \ ldr RT1, [RTAB, RT1]; \ eor rna, rna, RT0; \ ldr RT2, [RTAB, RT2]; \ - and RT0, RMASK, rb, lsl#3; \ + and RT0, RMASK, rb, lsl#2; \ ldr ra, [RTAB, ra]; \ \ eor rnb, rnb, RT1, ror #24; \ - and RT1, RMASK, rb, lsr#(8 - 3); \ + and RT1, RMASK, rb, lsr#(8 - 2); \ eor rnc, rnc, RT2, ror #16; \ - and RT2, RMASK, rb, lsr#(16 - 3); \ + and RT2, RMASK, rb, lsr#(16 - 2); \ eor rnd, rnd, ra, ror #8; \ ldr RT0, [RTAB, RT0]; \ - and rb, RMASK, rb, lsr#(24 - 3); \ + and rb, RMASK, rb, lsr#(24 - 2); \ \ ldr RT1, [RTAB, RT1]; \ eor rnb, rnb, RT0; \ ldr RT2, [RTAB, RT2]; \ - and RT0, RMASK, rc, lsl#3; \ + and RT0, RMASK, rc, lsl#2; \ ldr rb, [RTAB, rb]; \ \ eor rnc, rnc, RT1, ror #24; \ - and RT1, RMASK, rc, lsr#(8 - 3); \ + and RT1, RMASK, rc, lsr#(8 - 2); \ eor rnd, rnd, RT2, ror #16; \ - and RT2, RMASK, rc, lsr#(16 - 3); \ + and RT2, RMASK, rc, lsr#(16 - 2); \ eor rna, rna, rb, ror #8; \ ldr RT0, [RTAB, RT0]; \ - and rc, RMASK, rc, lsr#(24 - 3); \ + and rc, RMASK, rc, lsr#(24 - 2); \ \ ldr RT1, [RTAB, RT1]; \ eor rnc, rnc, RT0; \ ldr RT2, [RTAB, RT2]; \ - and RT0, RMASK, rd, lsl#3; \ + and RT0, RMASK, rd, lsl#2; \ ldr rc, [RTAB, rc]; \ \ eor rnd, rnd, RT1, ror #24; \ - and RT1, RMASK, rd, lsr#(8 - 3); \ + and RT1, RMASK, rd, lsr#(8 - 2); \ eor rna, rna, RT2, ror #16; \ - and RT2, RMASK, rd, lsr#(16 - 3); \ + and RT2, RMASK, rd, lsr#(16 - 2); \ eor rnb, rnb, rc, ror #8; \ ldr RT0, [RTAB, RT0]; \ - and rd, RMASK, rd, lsr#(24 - 3); \ + and rd, RMASK, rd, lsr#(24 - 2); \ \ ldr RT1, [RTAB, RT1]; \ eor rnd, rnd, RT0; \ @@ -416,51 +403,51 @@ _gcry_aes_arm_encrypt_block: eor rnc, rnc, rd, ror #8; #define do_lastdecround(ra, rb, rc, rd, rna, rnb, rnc, rnd) \ - and RT0, RMASK, ra, lsl#3; \ - and RT1, RMASK, ra, lsr#(8 - 3); \ - and RT2, RMASK, ra, lsr#(16 - 3); \ - ldr rna, [RTAB, RT0]; \ - and ra, RMASK, ra, lsr#(24 - 3); \ - ldr rnb, [RTAB, RT1]; \ - and RT0, RMASK, rb, lsl#3; \ - ldr rnc, [RTAB, RT2]; \ + and RT0, RMASK, ra; \ + and RT1, RMASK, ra, lsr#8; \ + and RT2, RMASK, ra, lsr#16; \ + ldrb rna, [RTAB, RT0]; \ + mov ra, ra, lsr#24; \ + ldrb rnb, [RTAB, RT1]; \ + and RT0, RMASK, rb; \ + ldrb rnc, [RTAB, RT2]; \ mov rnb, rnb, ror #24; \ - ldr rnd, [RTAB, ra]; \ - and RT1, RMASK, rb, lsr#(8 - 3); \ + ldrb rnd, [RTAB, ra]; \ + and RT1, RMASK, rb, lsr#8; \ mov rnc, rnc, ror #16; \ - and RT2, RMASK, rb, lsr#(16 - 3); \ + and RT2, RMASK, rb, lsr#16; \ mov rnd, rnd, ror #8; \ - ldr RT0, [RTAB, RT0]; \ - and rb, RMASK, rb, lsr#(24 - 3); \ - ldr RT1, [RTAB, RT1]; \ + ldrb RT0, [RTAB, RT0]; \ + mov rb, rb, lsr#24; \ + ldrb RT1, [RTAB, RT1]; \ \ orr rnb, rnb, RT0; \ - ldr RT2, [RTAB, RT2]; \ - and RT0, RMASK, rc, lsl#3; \ - ldr rb, [RTAB, rb]; \ + ldrb RT2, [RTAB, RT2]; \ + and RT0, RMASK, rc; \ + ldrb rb, [RTAB, rb]; \ orr rnc, rnc, RT1, ror #24; \ - and RT1, RMASK, rc, lsr#(8 - 3); \ + and RT1, RMASK, rc, lsr#8; \ orr rnd, rnd, RT2, ror #16; \ - and RT2, RMASK, rc, lsr#(16 - 3); \ + and RT2, RMASK, rc, lsr#16; \ orr rna, rna, rb, ror #8; \ - ldr RT0, [RTAB, RT0]; \ - and rc, RMASK, rc, lsr#(24 - 3); \ - ldr RT1, [RTAB, RT1]; \ + ldrb RT0, [RTAB, RT0]; \ + mov rc, rc, lsr#24; \ + ldrb RT1, [RTAB, RT1]; \ \ orr rnc, rnc, RT0; \ - ldr RT2, [RTAB, RT2]; \ - and RT0, RMASK, rd, lsl#3; \ - ldr rc, [RTAB, rc]; \ + ldrb RT2, [RTAB, RT2]; \ + and RT0, RMASK, rd; \ + ldrb rc, [RTAB, rc]; \ orr rnd, rnd, RT1, ror #24; \ - and RT1, RMASK, rd, lsr#(8 - 3); \ + and RT1, RMASK, rd, lsr#8; \ orr rna, rna, RT2, ror #16; \ - ldr RT0, [RTAB, RT0]; \ - and RT2, RMASK, rd, lsr#(16 - 3); \ - ldr RT1, [RTAB, RT1]; \ + ldrb RT0, [RTAB, RT0]; \ + and RT2, RMASK, rd, lsr#16; \ + ldrb RT1, [RTAB, RT1]; \ orr rnb, rnb, rc, ror #8; \ - ldr RT2, [RTAB, RT2]; \ - and rd, RMASK, rd, lsr#(24 - 3); \ - ldr rd, [RTAB, rd]; \ + ldrb RT2, [RTAB, RT2]; \ + mov rd, rd, lsr#24; \ + ldrb rd, [RTAB, rd]; \ \ orr rnd, rnd, RT0; \ orr rna, rna, RT1, ror #24; \ @@ -474,8 +461,11 @@ _gcry_aes_arm_encrypt_block: #define decround(round, ra, rb, rc, rd, rna, rnb, rnc, rnd, preload_key) \ do_decround(round, ra, rb, rc, rd, rna, rnb, rnc, rnd, preload_key); +#define set_last_round_rmask(_, __) \ + mov RMASK, #0xff; + #define lastdecround(round, ra, rb, rc, rd, rna, rnb, rnc, rnd) \ - add RTAB, #4; \ + add RTAB, #(4 * 256); \ do_lastdecround(ra, rb, rc, rd, rna, rnb, rnc, rnd); \ addroundkey(rna, rnb, rnc, rnd, ra, rb, rc, rd, dummy); @@ -489,6 +479,7 @@ _gcry_aes_arm_decrypt_block: * %r1: dst * %r2: src * %r3: number of rounds.. 10, 12 or 14 + * %st+0: decryption table */ push {%r4-%r11, %ip, %lr}; @@ -516,13 +507,12 @@ _gcry_aes_arm_decrypt_block: rev RD, RD; #endif 2: + ldr RTAB, [%sp, #40]; sub %sp, #16; - GET_DATA_POINTER(RTAB, .LtableD0, RMASK); - mov RMASK, #0xff; str %r1, [%sp, #4]; /* dst */ - mov RMASK, RMASK, lsl#3; /* byte mask */ + mov RMASK, RMASK, lsl#2; /* byte mask */ cmp %r3, #12; bge .Ldec_256; @@ -536,7 +526,7 @@ _gcry_aes_arm_decrypt_block: decround(4, RNA, RNB, RNC, RND, RA, RB, RC, RD, preload_first_key); decround(3, RA, RB, RC, RD, RNA, RNB, RNC, RND, preload_first_key); decround(2, RNA, RNB, RNC, RND, RA, RB, RC, RD, preload_first_key); - decround(1, RA, RB, RC, RD, RNA, RNB, RNC, RND, dummy); + decround(1, RA, RB, RC, RD, RNA, RNB, RNC, RND, set_last_round_rmask); lastdecround(0, RNA, RNB, RNC, RND, RA, RB, RC, RD); ldr RT0, [%sp, #4]; /* dst */ @@ -591,279 +581,5 @@ _gcry_aes_arm_decrypt_block: b .Ldec_tail; .size _gcry_aes_arm_encrypt_block,.-_gcry_aes_arm_encrypt_block; -.data - -/* Encryption tables */ -.align 5 -.type .LtableE0, %object -.type .LtableEs0, %object -.LtableE0: -.long 0xa56363c6 -.LtableEs0: -.long 0x00000063, 0x847c7cf8, 0x0000007c -.long 0x997777ee, 0x00000077, 0x8d7b7bf6, 0x0000007b -.long 0x0df2f2ff, 0x000000f2, 0xbd6b6bd6, 0x0000006b -.long 0xb16f6fde, 0x0000006f, 0x54c5c591, 0x000000c5 -.long 0x50303060, 0x00000030, 0x03010102, 0x00000001 -.long 0xa96767ce, 0x00000067, 0x7d2b2b56, 0x0000002b -.long 0x19fefee7, 0x000000fe, 0x62d7d7b5, 0x000000d7 -.long 0xe6abab4d, 0x000000ab, 0x9a7676ec, 0x00000076 -.long 0x45caca8f, 0x000000ca, 0x9d82821f, 0x00000082 -.long 0x40c9c989, 0x000000c9, 0x877d7dfa, 0x0000007d -.long 0x15fafaef, 0x000000fa, 0xeb5959b2, 0x00000059 -.long 0xc947478e, 0x00000047, 0x0bf0f0fb, 0x000000f0 -.long 0xecadad41, 0x000000ad, 0x67d4d4b3, 0x000000d4 -.long 0xfda2a25f, 0x000000a2, 0xeaafaf45, 0x000000af -.long 0xbf9c9c23, 0x0000009c, 0xf7a4a453, 0x000000a4 -.long 0x967272e4, 0x00000072, 0x5bc0c09b, 0x000000c0 -.long 0xc2b7b775, 0x000000b7, 0x1cfdfde1, 0x000000fd -.long 0xae93933d, 0x00000093, 0x6a26264c, 0x00000026 -.long 0x5a36366c, 0x00000036, 0x413f3f7e, 0x0000003f -.long 0x02f7f7f5, 0x000000f7, 0x4fcccc83, 0x000000cc -.long 0x5c343468, 0x00000034, 0xf4a5a551, 0x000000a5 -.long 0x34e5e5d1, 0x000000e5, 0x08f1f1f9, 0x000000f1 -.long 0x937171e2, 0x00000071, 0x73d8d8ab, 0x000000d8 -.long 0x53313162, 0x00000031, 0x3f15152a, 0x00000015 -.long 0x0c040408, 0x00000004, 0x52c7c795, 0x000000c7 -.long 0x65232346, 0x00000023, 0x5ec3c39d, 0x000000c3 -.long 0x28181830, 0x00000018, 0xa1969637, 0x00000096 -.long 0x0f05050a, 0x00000005, 0xb59a9a2f, 0x0000009a -.long 0x0907070e, 0x00000007, 0x36121224, 0x00000012 -.long 0x9b80801b, 0x00000080, 0x3de2e2df, 0x000000e2 -.long 0x26ebebcd, 0x000000eb, 0x6927274e, 0x00000027 -.long 0xcdb2b27f, 0x000000b2, 0x9f7575ea, 0x00000075 -.long 0x1b090912, 0x00000009, 0x9e83831d, 0x00000083 -.long 0x742c2c58, 0x0000002c, 0x2e1a1a34, 0x0000001a -.long 0x2d1b1b36, 0x0000001b, 0xb26e6edc, 0x0000006e -.long 0xee5a5ab4, 0x0000005a, 0xfba0a05b, 0x000000a0 -.long 0xf65252a4, 0x00000052, 0x4d3b3b76, 0x0000003b -.long 0x61d6d6b7, 0x000000d6, 0xceb3b37d, 0x000000b3 -.long 0x7b292952, 0x00000029, 0x3ee3e3dd, 0x000000e3 -.long 0x712f2f5e, 0x0000002f, 0x97848413, 0x00000084 -.long 0xf55353a6, 0x00000053, 0x68d1d1b9, 0x000000d1 -.long 0x00000000, 0x00000000, 0x2cededc1, 0x000000ed -.long 0x60202040, 0x00000020, 0x1ffcfce3, 0x000000fc -.long 0xc8b1b179, 0x000000b1, 0xed5b5bb6, 0x0000005b -.long 0xbe6a6ad4, 0x0000006a, 0x46cbcb8d, 0x000000cb -.long 0xd9bebe67, 0x000000be, 0x4b393972, 0x00000039 -.long 0xde4a4a94, 0x0000004a, 0xd44c4c98, 0x0000004c -.long 0xe85858b0, 0x00000058, 0x4acfcf85, 0x000000cf -.long 0x6bd0d0bb, 0x000000d0, 0x2aefefc5, 0x000000ef -.long 0xe5aaaa4f, 0x000000aa, 0x16fbfbed, 0x000000fb -.long 0xc5434386, 0x00000043, 0xd74d4d9a, 0x0000004d -.long 0x55333366, 0x00000033, 0x94858511, 0x00000085 -.long 0xcf45458a, 0x00000045, 0x10f9f9e9, 0x000000f9 -.long 0x06020204, 0x00000002, 0x817f7ffe, 0x0000007f -.long 0xf05050a0, 0x00000050, 0x443c3c78, 0x0000003c -.long 0xba9f9f25, 0x0000009f, 0xe3a8a84b, 0x000000a8 -.long 0xf35151a2, 0x00000051, 0xfea3a35d, 0x000000a3 -.long 0xc0404080, 0x00000040, 0x8a8f8f05, 0x0000008f -.long 0xad92923f, 0x00000092, 0xbc9d9d21, 0x0000009d -.long 0x48383870, 0x00000038, 0x04f5f5f1, 0x000000f5 -.long 0xdfbcbc63, 0x000000bc, 0xc1b6b677, 0x000000b6 -.long 0x75dadaaf, 0x000000da, 0x63212142, 0x00000021 -.long 0x30101020, 0x00000010, 0x1affffe5, 0x000000ff -.long 0x0ef3f3fd, 0x000000f3, 0x6dd2d2bf, 0x000000d2 -.long 0x4ccdcd81, 0x000000cd, 0x140c0c18, 0x0000000c -.long 0x35131326, 0x00000013, 0x2fececc3, 0x000000ec -.long 0xe15f5fbe, 0x0000005f, 0xa2979735, 0x00000097 -.long 0xcc444488, 0x00000044, 0x3917172e, 0x00000017 -.long 0x57c4c493, 0x000000c4, 0xf2a7a755, 0x000000a7 -.long 0x827e7efc, 0x0000007e, 0x473d3d7a, 0x0000003d -.long 0xac6464c8, 0x00000064, 0xe75d5dba, 0x0000005d -.long 0x2b191932, 0x00000019, 0x957373e6, 0x00000073 -.long 0xa06060c0, 0x00000060, 0x98818119, 0x00000081 -.long 0xd14f4f9e, 0x0000004f, 0x7fdcdca3, 0x000000dc -.long 0x66222244, 0x00000022, 0x7e2a2a54, 0x0000002a -.long 0xab90903b, 0x00000090, 0x8388880b, 0x00000088 -.long 0xca46468c, 0x00000046, 0x29eeeec7, 0x000000ee -.long 0xd3b8b86b, 0x000000b8, 0x3c141428, 0x00000014 -.long 0x79dedea7, 0x000000de, 0xe25e5ebc, 0x0000005e -.long 0x1d0b0b16, 0x0000000b, 0x76dbdbad, 0x000000db -.long 0x3be0e0db, 0x000000e0, 0x56323264, 0x00000032 -.long 0x4e3a3a74, 0x0000003a, 0x1e0a0a14, 0x0000000a -.long 0xdb494992, 0x00000049, 0x0a06060c, 0x00000006 -.long 0x6c242448, 0x00000024, 0xe45c5cb8, 0x0000005c -.long 0x5dc2c29f, 0x000000c2, 0x6ed3d3bd, 0x000000d3 -.long 0xefacac43, 0x000000ac, 0xa66262c4, 0x00000062 -.long 0xa8919139, 0x00000091, 0xa4959531, 0x00000095 -.long 0x37e4e4d3, 0x000000e4, 0x8b7979f2, 0x00000079 -.long 0x32e7e7d5, 0x000000e7, 0x43c8c88b, 0x000000c8 -.long 0x5937376e, 0x00000037, 0xb76d6dda, 0x0000006d -.long 0x8c8d8d01, 0x0000008d, 0x64d5d5b1, 0x000000d5 -.long 0xd24e4e9c, 0x0000004e, 0xe0a9a949, 0x000000a9 -.long 0xb46c6cd8, 0x0000006c, 0xfa5656ac, 0x00000056 -.long 0x07f4f4f3, 0x000000f4, 0x25eaeacf, 0x000000ea -.long 0xaf6565ca, 0x00000065, 0x8e7a7af4, 0x0000007a -.long 0xe9aeae47, 0x000000ae, 0x18080810, 0x00000008 -.long 0xd5baba6f, 0x000000ba, 0x887878f0, 0x00000078 -.long 0x6f25254a, 0x00000025, 0x722e2e5c, 0x0000002e -.long 0x241c1c38, 0x0000001c, 0xf1a6a657, 0x000000a6 -.long 0xc7b4b473, 0x000000b4, 0x51c6c697, 0x000000c6 -.long 0x23e8e8cb, 0x000000e8, 0x7cdddda1, 0x000000dd -.long 0x9c7474e8, 0x00000074, 0x211f1f3e, 0x0000001f -.long 0xdd4b4b96, 0x0000004b, 0xdcbdbd61, 0x000000bd -.long 0x868b8b0d, 0x0000008b, 0x858a8a0f, 0x0000008a -.long 0x907070e0, 0x00000070, 0x423e3e7c, 0x0000003e -.long 0xc4b5b571, 0x000000b5, 0xaa6666cc, 0x00000066 -.long 0xd8484890, 0x00000048, 0x05030306, 0x00000003 -.long 0x01f6f6f7, 0x000000f6, 0x120e0e1c, 0x0000000e -.long 0xa36161c2, 0x00000061, 0x5f35356a, 0x00000035 -.long 0xf95757ae, 0x00000057, 0xd0b9b969, 0x000000b9 -.long 0x91868617, 0x00000086, 0x58c1c199, 0x000000c1 -.long 0x271d1d3a, 0x0000001d, 0xb99e9e27, 0x0000009e -.long 0x38e1e1d9, 0x000000e1, 0x13f8f8eb, 0x000000f8 -.long 0xb398982b, 0x00000098, 0x33111122, 0x00000011 -.long 0xbb6969d2, 0x00000069, 0x70d9d9a9, 0x000000d9 -.long 0x898e8e07, 0x0000008e, 0xa7949433, 0x00000094 -.long 0xb69b9b2d, 0x0000009b, 0x221e1e3c, 0x0000001e -.long 0x92878715, 0x00000087, 0x20e9e9c9, 0x000000e9 -.long 0x49cece87, 0x000000ce, 0xff5555aa, 0x00000055 -.long 0x78282850, 0x00000028, 0x7adfdfa5, 0x000000df -.long 0x8f8c8c03, 0x0000008c, 0xf8a1a159, 0x000000a1 -.long 0x80898909, 0x00000089, 0x170d0d1a, 0x0000000d -.long 0xdabfbf65, 0x000000bf, 0x31e6e6d7, 0x000000e6 -.long 0xc6424284, 0x00000042, 0xb86868d0, 0x00000068 -.long 0xc3414182, 0x00000041, 0xb0999929, 0x00000099 -.long 0x772d2d5a, 0x0000002d, 0x110f0f1e, 0x0000000f -.long 0xcbb0b07b, 0x000000b0, 0xfc5454a8, 0x00000054 -.long 0xd6bbbb6d, 0x000000bb, 0x3a16162c, 0x00000016 - -/* Decryption tables */ -.align 5 -.type .LtableD0, %object -.type .LtableDs0, %object -.LtableD0: -.long 0x50a7f451 -.LtableDs0: -.long 0x00000052, 0x5365417e, 0x00000009 -.long 0xc3a4171a, 0x0000006a, 0x965e273a, 0x000000d5 -.long 0xcb6bab3b, 0x00000030, 0xf1459d1f, 0x00000036 -.long 0xab58faac, 0x000000a5, 0x9303e34b, 0x00000038 -.long 0x55fa3020, 0x000000bf, 0xf66d76ad, 0x00000040 -.long 0x9176cc88, 0x000000a3, 0x254c02f5, 0x0000009e -.long 0xfcd7e54f, 0x00000081, 0xd7cb2ac5, 0x000000f3 -.long 0x80443526, 0x000000d7, 0x8fa362b5, 0x000000fb -.long 0x495ab1de, 0x0000007c, 0x671bba25, 0x000000e3 -.long 0x980eea45, 0x00000039, 0xe1c0fe5d, 0x00000082 -.long 0x02752fc3, 0x0000009b, 0x12f04c81, 0x0000002f -.long 0xa397468d, 0x000000ff, 0xc6f9d36b, 0x00000087 -.long 0xe75f8f03, 0x00000034, 0x959c9215, 0x0000008e -.long 0xeb7a6dbf, 0x00000043, 0xda595295, 0x00000044 -.long 0x2d83bed4, 0x000000c4, 0xd3217458, 0x000000de -.long 0x2969e049, 0x000000e9, 0x44c8c98e, 0x000000cb -.long 0x6a89c275, 0x00000054, 0x78798ef4, 0x0000007b -.long 0x6b3e5899, 0x00000094, 0xdd71b927, 0x00000032 -.long 0xb64fe1be, 0x000000a6, 0x17ad88f0, 0x000000c2 -.long 0x66ac20c9, 0x00000023, 0xb43ace7d, 0x0000003d -.long 0x184adf63, 0x000000ee, 0x82311ae5, 0x0000004c -.long 0x60335197, 0x00000095, 0x457f5362, 0x0000000b -.long 0xe07764b1, 0x00000042, 0x84ae6bbb, 0x000000fa -.long 0x1ca081fe, 0x000000c3, 0x942b08f9, 0x0000004e -.long 0x58684870, 0x00000008, 0x19fd458f, 0x0000002e -.long 0x876cde94, 0x000000a1, 0xb7f87b52, 0x00000066 -.long 0x23d373ab, 0x00000028, 0xe2024b72, 0x000000d9 -.long 0x578f1fe3, 0x00000024, 0x2aab5566, 0x000000b2 -.long 0x0728ebb2, 0x00000076, 0x03c2b52f, 0x0000005b -.long 0x9a7bc586, 0x000000a2, 0xa50837d3, 0x00000049 -.long 0xf2872830, 0x0000006d, 0xb2a5bf23, 0x0000008b -.long 0xba6a0302, 0x000000d1, 0x5c8216ed, 0x00000025 -.long 0x2b1ccf8a, 0x00000072, 0x92b479a7, 0x000000f8 -.long 0xf0f207f3, 0x000000f6, 0xa1e2694e, 0x00000064 -.long 0xcdf4da65, 0x00000086, 0xd5be0506, 0x00000068 -.long 0x1f6234d1, 0x00000098, 0x8afea6c4, 0x00000016 -.long 0x9d532e34, 0x000000d4, 0xa055f3a2, 0x000000a4 -.long 0x32e18a05, 0x0000005c, 0x75ebf6a4, 0x000000cc -.long 0x39ec830b, 0x0000005d, 0xaaef6040, 0x00000065 -.long 0x069f715e, 0x000000b6, 0x51106ebd, 0x00000092 -.long 0xf98a213e, 0x0000006c, 0x3d06dd96, 0x00000070 -.long 0xae053edd, 0x00000048, 0x46bde64d, 0x00000050 -.long 0xb58d5491, 0x000000fd, 0x055dc471, 0x000000ed -.long 0x6fd40604, 0x000000b9, 0xff155060, 0x000000da -.long 0x24fb9819, 0x0000005e, 0x97e9bdd6, 0x00000015 -.long 0xcc434089, 0x00000046, 0x779ed967, 0x00000057 -.long 0xbd42e8b0, 0x000000a7, 0x888b8907, 0x0000008d -.long 0x385b19e7, 0x0000009d, 0xdbeec879, 0x00000084 -.long 0x470a7ca1, 0x00000090, 0xe90f427c, 0x000000d8 -.long 0xc91e84f8, 0x000000ab, 0x00000000, 0x00000000 -.long 0x83868009, 0x0000008c, 0x48ed2b32, 0x000000bc -.long 0xac70111e, 0x000000d3, 0x4e725a6c, 0x0000000a -.long 0xfbff0efd, 0x000000f7, 0x5638850f, 0x000000e4 -.long 0x1ed5ae3d, 0x00000058, 0x27392d36, 0x00000005 -.long 0x64d90f0a, 0x000000b8, 0x21a65c68, 0x000000b3 -.long 0xd1545b9b, 0x00000045, 0x3a2e3624, 0x00000006 -.long 0xb1670a0c, 0x000000d0, 0x0fe75793, 0x0000002c -.long 0xd296eeb4, 0x0000001e, 0x9e919b1b, 0x0000008f -.long 0x4fc5c080, 0x000000ca, 0xa220dc61, 0x0000003f -.long 0x694b775a, 0x0000000f, 0x161a121c, 0x00000002 -.long 0x0aba93e2, 0x000000c1, 0xe52aa0c0, 0x000000af -.long 0x43e0223c, 0x000000bd, 0x1d171b12, 0x00000003 -.long 0x0b0d090e, 0x00000001, 0xadc78bf2, 0x00000013 -.long 0xb9a8b62d, 0x0000008a, 0xc8a91e14, 0x0000006b -.long 0x8519f157, 0x0000003a, 0x4c0775af, 0x00000091 -.long 0xbbdd99ee, 0x00000011, 0xfd607fa3, 0x00000041 -.long 0x9f2601f7, 0x0000004f, 0xbcf5725c, 0x00000067 -.long 0xc53b6644, 0x000000dc, 0x347efb5b, 0x000000ea -.long 0x7629438b, 0x00000097, 0xdcc623cb, 0x000000f2 -.long 0x68fcedb6, 0x000000cf, 0x63f1e4b8, 0x000000ce -.long 0xcadc31d7, 0x000000f0, 0x10856342, 0x000000b4 -.long 0x40229713, 0x000000e6, 0x2011c684, 0x00000073 -.long 0x7d244a85, 0x00000096, 0xf83dbbd2, 0x000000ac -.long 0x1132f9ae, 0x00000074, 0x6da129c7, 0x00000022 -.long 0x4b2f9e1d, 0x000000e7, 0xf330b2dc, 0x000000ad -.long 0xec52860d, 0x00000035, 0xd0e3c177, 0x00000085 -.long 0x6c16b32b, 0x000000e2, 0x99b970a9, 0x000000f9 -.long 0xfa489411, 0x00000037, 0x2264e947, 0x000000e8 -.long 0xc48cfca8, 0x0000001c, 0x1a3ff0a0, 0x00000075 -.long 0xd82c7d56, 0x000000df, 0xef903322, 0x0000006e -.long 0xc74e4987, 0x00000047, 0xc1d138d9, 0x000000f1 -.long 0xfea2ca8c, 0x0000001a, 0x360bd498, 0x00000071 -.long 0xcf81f5a6, 0x0000001d, 0x28de7aa5, 0x00000029 -.long 0x268eb7da, 0x000000c5, 0xa4bfad3f, 0x00000089 -.long 0xe49d3a2c, 0x0000006f, 0x0d927850, 0x000000b7 -.long 0x9bcc5f6a, 0x00000062, 0x62467e54, 0x0000000e -.long 0xc2138df6, 0x000000aa, 0xe8b8d890, 0x00000018 -.long 0x5ef7392e, 0x000000be, 0xf5afc382, 0x0000001b -.long 0xbe805d9f, 0x000000fc, 0x7c93d069, 0x00000056 -.long 0xa92dd56f, 0x0000003e, 0xb31225cf, 0x0000004b -.long 0x3b99acc8, 0x000000c6, 0xa77d1810, 0x000000d2 -.long 0x6e639ce8, 0x00000079, 0x7bbb3bdb, 0x00000020 -.long 0x097826cd, 0x0000009a, 0xf418596e, 0x000000db -.long 0x01b79aec, 0x000000c0, 0xa89a4f83, 0x000000fe -.long 0x656e95e6, 0x00000078, 0x7ee6ffaa, 0x000000cd -.long 0x08cfbc21, 0x0000005a, 0xe6e815ef, 0x000000f4 -.long 0xd99be7ba, 0x0000001f, 0xce366f4a, 0x000000dd -.long 0xd4099fea, 0x000000a8, 0xd67cb029, 0x00000033 -.long 0xafb2a431, 0x00000088, 0x31233f2a, 0x00000007 -.long 0x3094a5c6, 0x000000c7, 0xc066a235, 0x00000031 -.long 0x37bc4e74, 0x000000b1, 0xa6ca82fc, 0x00000012 -.long 0xb0d090e0, 0x00000010, 0x15d8a733, 0x00000059 -.long 0x4a9804f1, 0x00000027, 0xf7daec41, 0x00000080 -.long 0x0e50cd7f, 0x000000ec, 0x2ff69117, 0x0000005f -.long 0x8dd64d76, 0x00000060, 0x4db0ef43, 0x00000051 -.long 0x544daacc, 0x0000007f, 0xdf0496e4, 0x000000a9 -.long 0xe3b5d19e, 0x00000019, 0x1b886a4c, 0x000000b5 -.long 0xb81f2cc1, 0x0000004a, 0x7f516546, 0x0000000d -.long 0x04ea5e9d, 0x0000002d, 0x5d358c01, 0x000000e5 -.long 0x737487fa, 0x0000007a, 0x2e410bfb, 0x0000009f -.long 0x5a1d67b3, 0x00000093, 0x52d2db92, 0x000000c9 -.long 0x335610e9, 0x0000009c, 0x1347d66d, 0x000000ef -.long 0x8c61d79a, 0x000000a0, 0x7a0ca137, 0x000000e0 -.long 0x8e14f859, 0x0000003b, 0x893c13eb, 0x0000004d -.long 0xee27a9ce, 0x000000ae, 0x35c961b7, 0x0000002a -.long 0xede51ce1, 0x000000f5, 0x3cb1477a, 0x000000b0 -.long 0x59dfd29c, 0x000000c8, 0x3f73f255, 0x000000eb -.long 0x79ce1418, 0x000000bb, 0xbf37c773, 0x0000003c -.long 0xeacdf753, 0x00000083, 0x5baafd5f, 0x00000053 -.long 0x146f3ddf, 0x00000099, 0x86db4478, 0x00000061 -.long 0x81f3afca, 0x00000017, 0x3ec468b9, 0x0000002b -.long 0x2c342438, 0x00000004, 0x5f40a3c2, 0x0000007e -.long 0x72c31d16, 0x000000ba, 0x0c25e2bc, 0x00000077 -.long 0x8b493c28, 0x000000d6, 0x41950dff, 0x00000026 -.long 0x7101a839, 0x000000e1, 0xdeb30c08, 0x00000069 -.long 0x9ce4b4d8, 0x00000014, 0x90c15664, 0x00000063 -.long 0x6184cb7b, 0x00000055, 0x70b632d5, 0x00000021 -.long 0x745c6c48, 0x0000000c, 0x4257b8d0, 0x0000007d - #endif /*HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS*/ #endif /*__ARMEL__ */ diff --git a/cipher/rijndael-internal.h b/cipher/rijndael-internal.h index 9898f0c..7bc3790 100644 --- a/cipher/rijndael-internal.h +++ b/cipher/rijndael-internal.h @@ -79,6 +79,7 @@ struct RIJNDAEL_context_s; typedef unsigned int (*rijndael_cryptfn_t)(const struct RIJNDAEL_context_s *ctx, unsigned char *bx, const unsigned char *ax); +typedef void (*rijndael_prefetchfn_t)(void); /* Our context object. */ typedef struct RIJNDAEL_context_s @@ -115,6 +116,8 @@ typedef struct RIJNDAEL_context_s #endif /*USE_AESNI*/ rijndael_cryptfn_t encrypt_fn; rijndael_cryptfn_t decrypt_fn; + rijndael_prefetchfn_t prefetch_enc_fn; + rijndael_prefetchfn_t prefetch_dec_fn; } RIJNDAEL_context ATTR_ALIGNED_16; /* Macros defining alias for the keyschedules. */ diff --git a/cipher/rijndael-tables.h b/cipher/rijndael-tables.h index b6a5b15..8359470 100644 --- a/cipher/rijndael-tables.h +++ b/cipher/rijndael-tables.h @@ -21,1662 +21,184 @@ /* To keep the actual implementation at a readable size we use this include file to define the tables. */ -static const unsigned char S[256] = +static const u32 encT[256] = { - 99, 124, 119, 123, 242, 107, 111, 197, - 48, 1, 103, 43, 254, 215, 171, 118, - 202, 130, 201, 125, 250, 89, 71, 240, - 173, 212, 162, 175, 156, 164, 114, 192, - 183, 253, 147, 38, 54, 63, 247, 204, - 52, 165, 229, 241, 113, 216, 49, 21, - 4, 199, 35, 195, 24, 150, 5, 154, - 7, 18, 128, 226, 235, 39, 178, 117, - 9, 131, 44, 26, 27, 110, 90, 160, - 82, 59, 214, 179, 41, 227, 47, 132, - 83, 209, 0, 237, 32, 252, 177, 91, - 106, 203, 190, 57, 74, 76, 88, 207, - 208, 239, 170, 251, 67, 77, 51, 133, - 69, 249, 2, 127, 80, 60, 159, 168, - 81, 163, 64, 143, 146, 157, 56, 245, - 188, 182, 218, 33, 16, 255, 243, 210, - 205, 12, 19, 236, 95, 151, 68, 23, - 196, 167, 126, 61, 100, 93, 25, 115, - 96, 129, 79, 220, 34, 42, 144, 136, - 70, 238, 184, 20, 222, 94, 11, 219, - 224, 50, 58, 10, 73, 6, 36, 92, - 194, 211, 172, 98, 145, 149, 228, 121, - 231, 200, 55, 109, 141, 213, 78, 169, - 108, 86, 244, 234, 101, 122, 174, 8, - 186, 120, 37, 46, 28, 166, 180, 198, - 232, 221, 116, 31, 75, 189, 139, 138, - 112, 62, 181, 102, 72, 3, 246, 14, - 97, 53, 87, 185, 134, 193, 29, 158, - 225, 248, 152, 17, 105, 217, 142, 148, - 155, 30, 135, 233, 206, 85, 40, 223, - 140, 161, 137, 13, 191, 230, 66, 104, - 65, 153, 45, 15, 176, 84, 187, 22 + 0xa56363c6, 0x847c7cf8, 0x997777ee, 0x8d7b7bf6, + 0x0df2f2ff, 0xbd6b6bd6, 0xb16f6fde, 0x54c5c591, + 0x50303060, 0x03010102, 0xa96767ce, 0x7d2b2b56, + 0x19fefee7, 0x62d7d7b5, 0xe6abab4d, 0x9a7676ec, + 0x45caca8f, 0x9d82821f, 0x40c9c989, 0x877d7dfa, + 0x15fafaef, 0xeb5959b2, 0xc947478e, 0x0bf0f0fb, + 0xecadad41, 0x67d4d4b3, 0xfda2a25f, 0xeaafaf45, + 0xbf9c9c23, 0xf7a4a453, 0x967272e4, 0x5bc0c09b, + 0xc2b7b775, 0x1cfdfde1, 0xae93933d, 0x6a26264c, + 0x5a36366c, 0x413f3f7e, 0x02f7f7f5, 0x4fcccc83, + 0x5c343468, 0xf4a5a551, 0x34e5e5d1, 0x08f1f1f9, + 0x937171e2, 0x73d8d8ab, 0x53313162, 0x3f15152a, + 0x0c040408, 0x52c7c795, 0x65232346, 0x5ec3c39d, + 0x28181830, 0xa1969637, 0x0f05050a, 0xb59a9a2f, + 0x0907070e, 0x36121224, 0x9b80801b, 0x3de2e2df, + 0x26ebebcd, 0x6927274e, 0xcdb2b27f, 0x9f7575ea, + 0x1b090912, 0x9e83831d, 0x742c2c58, 0x2e1a1a34, + 0x2d1b1b36, 0xb26e6edc, 0xee5a5ab4, 0xfba0a05b, + 0xf65252a4, 0x4d3b3b76, 0x61d6d6b7, 0xceb3b37d, + 0x7b292952, 0x3ee3e3dd, 0x712f2f5e, 0x97848413, + 0xf55353a6, 0x68d1d1b9, 0x00000000, 0x2cededc1, + 0x60202040, 0x1ffcfce3, 0xc8b1b179, 0xed5b5bb6, + 0xbe6a6ad4, 0x46cbcb8d, 0xd9bebe67, 0x4b393972, + 0xde4a4a94, 0xd44c4c98, 0xe85858b0, 0x4acfcf85, + 0x6bd0d0bb, 0x2aefefc5, 0xe5aaaa4f, 0x16fbfbed, + 0xc5434386, 0xd74d4d9a, 0x55333366, 0x94858511, + 0xcf45458a, 0x10f9f9e9, 0x06020204, 0x817f7ffe, + 0xf05050a0, 0x443c3c78, 0xba9f9f25, 0xe3a8a84b, + 0xf35151a2, 0xfea3a35d, 0xc0404080, 0x8a8f8f05, + 0xad92923f, 0xbc9d9d21, 0x48383870, 0x04f5f5f1, + 0xdfbcbc63, 0xc1b6b677, 0x75dadaaf, 0x63212142, + 0x30101020, 0x1affffe5, 0x0ef3f3fd, 0x6dd2d2bf, + 0x4ccdcd81, 0x140c0c18, 0x35131326, 0x2fececc3, + 0xe15f5fbe, 0xa2979735, 0xcc444488, 0x3917172e, + 0x57c4c493, 0xf2a7a755, 0x827e7efc, 0x473d3d7a, + 0xac6464c8, 0xe75d5dba, 0x2b191932, 0x957373e6, + 0xa06060c0, 0x98818119, 0xd14f4f9e, 0x7fdcdca3, + 0x66222244, 0x7e2a2a54, 0xab90903b, 0x8388880b, + 0xca46468c, 0x29eeeec7, 0xd3b8b86b, 0x3c141428, + 0x79dedea7, 0xe25e5ebc, 0x1d0b0b16, 0x76dbdbad, + 0x3be0e0db, 0x56323264, 0x4e3a3a74, 0x1e0a0a14, + 0xdb494992, 0x0a06060c, 0x6c242448, 0xe45c5cb8, + 0x5dc2c29f, 0x6ed3d3bd, 0xefacac43, 0xa66262c4, + 0xa8919139, 0xa4959531, 0x37e4e4d3, 0x8b7979f2, + 0x32e7e7d5, 0x43c8c88b, 0x5937376e, 0xb76d6dda, + 0x8c8d8d01, 0x64d5d5b1, 0xd24e4e9c, 0xe0a9a949, + 0xb46c6cd8, 0xfa5656ac, 0x07f4f4f3, 0x25eaeacf, + 0xaf6565ca, 0x8e7a7af4, 0xe9aeae47, 0x18080810, + 0xd5baba6f, 0x887878f0, 0x6f25254a, 0x722e2e5c, + 0x241c1c38, 0xf1a6a657, 0xc7b4b473, 0x51c6c697, + 0x23e8e8cb, 0x7cdddda1, 0x9c7474e8, 0x211f1f3e, + 0xdd4b4b96, 0xdcbdbd61, 0x868b8b0d, 0x858a8a0f, + 0x907070e0, 0x423e3e7c, 0xc4b5b571, 0xaa6666cc, + 0xd8484890, 0x05030306, 0x01f6f6f7, 0x120e0e1c, + 0xa36161c2, 0x5f35356a, 0xf95757ae, 0xd0b9b969, + 0x91868617, 0x58c1c199, 0x271d1d3a, 0xb99e9e27, + 0x38e1e1d9, 0x13f8f8eb, 0xb398982b, 0x33111122, + 0xbb6969d2, 0x70d9d9a9, 0x898e8e07, 0xa7949433, + 0xb69b9b2d, 0x221e1e3c, 0x92878715, 0x20e9e9c9, + 0x49cece87, 0xff5555aa, 0x78282850, 0x7adfdfa5, + 0x8f8c8c03, 0xf8a1a159, 0x80898909, 0x170d0d1a, + 0xdabfbf65, 0x31e6e6d7, 0xc6424284, 0xb86868d0, + 0xc3414182, 0xb0999929, 0x772d2d5a, 0x110f0f1e, + 0xcbb0b07b, 0xfc5454a8, 0xd6bbbb6d, 0x3a16162c }; - -static const unsigned char T1[256][4] = - { - { 0xc6,0x63,0x63,0xa5 }, { 0xf8,0x7c,0x7c,0x84 }, - { 0xee,0x77,0x77,0x99 }, { 0xf6,0x7b,0x7b,0x8d }, - { 0xff,0xf2,0xf2,0x0d }, { 0xd6,0x6b,0x6b,0xbd }, - { 0xde,0x6f,0x6f,0xb1 }, { 0x91,0xc5,0xc5,0x54 }, - { 0x60,0x30,0x30,0x50 }, { 0x02,0x01,0x01,0x03 }, - { 0xce,0x67,0x67,0xa9 }, { 0x56,0x2b,0x2b,0x7d }, - { 0xe7,0xfe,0xfe,0x19 }, { 0xb5,0xd7,0xd7,0x62 }, - { 0x4d,0xab,0xab,0xe6 }, { 0xec,0x76,0x76,0x9a }, - { 0x8f,0xca,0xca,0x45 }, { 0x1f,0x82,0x82,0x9d }, - { 0x89,0xc9,0xc9,0x40 }, { 0xfa,0x7d,0x7d,0x87 }, - { 0xef,0xfa,0xfa,0x15 }, { 0xb2,0x59,0x59,0xeb }, - { 0x8e,0x47,0x47,0xc9 }, { 0xfb,0xf0,0xf0,0x0b }, - { 0x41,0xad,0xad,0xec }, { 0xb3,0xd4,0xd4,0x67 }, - { 0x5f,0xa2,0xa2,0xfd }, { 0x45,0xaf,0xaf,0xea }, - { 0x23,0x9c,0x9c,0xbf }, { 0x53,0xa4,0xa4,0xf7 }, - { 0xe4,0x72,0x72,0x96 }, { 0x9b,0xc0,0xc0,0x5b }, - { 0x75,0xb7,0xb7,0xc2 }, { 0xe1,0xfd,0xfd,0x1c }, - { 0x3d,0x93,0x93,0xae }, { 0x4c,0x26,0x26,0x6a }, - { 0x6c,0x36,0x36,0x5a }, { 0x7e,0x3f,0x3f,0x41 }, - { 0xf5,0xf7,0xf7,0x02 }, { 0x83,0xcc,0xcc,0x4f }, - { 0x68,0x34,0x34,0x5c }, { 0x51,0xa5,0xa5,0xf4 }, - { 0xd1,0xe5,0xe5,0x34 }, { 0xf9,0xf1,0xf1,0x08 }, - { 0xe2,0x71,0x71,0x93 }, { 0xab,0xd8,0xd8,0x73 }, - { 0x62,0x31,0x31,0x53 }, { 0x2a,0x15,0x15,0x3f }, - { 0x08,0x04,0x04,0x0c }, { 0x95,0xc7,0xc7,0x52 }, - { 0x46,0x23,0x23,0x65 }, { 0x9d,0xc3,0xc3,0x5e }, - { 0x30,0x18,0x18,0x28 }, { 0x37,0x96,0x96,0xa1 }, - { 0x0a,0x05,0x05,0x0f }, { 0x2f,0x9a,0x9a,0xb5 }, - { 0x0e,0x07,0x07,0x09 }, { 0x24,0x12,0x12,0x36 }, - { 0x1b,0x80,0x80,0x9b }, { 0xdf,0xe2,0xe2,0x3d }, - { 0xcd,0xeb,0xeb,0x26 }, { 0x4e,0x27,0x27,0x69 }, - { 0x7f,0xb2,0xb2,0xcd }, { 0xea,0x75,0x75,0x9f }, - { 0x12,0x09,0x09,0x1b }, { 0x1d,0x83,0x83,0x9e }, - { 0x58,0x2c,0x2c,0x74 }, { 0x34,0x1a,0x1a,0x2e }, - { 0x36,0x1b,0x1b,0x2d }, { 0xdc,0x6e,0x6e,0xb2 }, - { 0xb4,0x5a,0x5a,0xee }, { 0x5b,0xa0,0xa0,0xfb }, - { 0xa4,0x52,0x52,0xf6 }, { 0x76,0x3b,0x3b,0x4d }, - { 0xb7,0xd6,0xd6,0x61 }, { 0x7d,0xb3,0xb3,0xce }, - { 0x52,0x29,0x29,0x7b }, { 0xdd,0xe3,0xe3,0x3e }, - { 0x5e,0x2f,0x2f,0x71 }, { 0x13,0x84,0x84,0x97 }, - { 0xa6,0x53,0x53,0xf5 }, { 0xb9,0xd1,0xd1,0x68 }, - { 0x00,0x00,0x00,0x00 }, { 0xc1,0xed,0xed,0x2c }, - { 0x40,0x20,0x20,0x60 }, { 0xe3,0xfc,0xfc,0x1f }, - { 0x79,0xb1,0xb1,0xc8 }, { 0xb6,0x5b,0x5b,0xed }, - { 0xd4,0x6a,0x6a,0xbe }, { 0x8d,0xcb,0xcb,0x46 }, - { 0x67,0xbe,0xbe,0xd9 }, { 0x72,0x39,0x39,0x4b }, - { 0x94,0x4a,0x4a,0xde }, { 0x98,0x4c,0x4c,0xd4 }, - { 0xb0,0x58,0x58,0xe8 }, { 0x85,0xcf,0xcf,0x4a }, - { 0xbb,0xd0,0xd0,0x6b }, { 0xc5,0xef,0xef,0x2a }, - { 0x4f,0xaa,0xaa,0xe5 }, { 0xed,0xfb,0xfb,0x16 }, - { 0x86,0x43,0x43,0xc5 }, { 0x9a,0x4d,0x4d,0xd7 }, - { 0x66,0x33,0x33,0x55 }, { 0x11,0x85,0x85,0x94 }, - { 0x8a,0x45,0x45,0xcf }, { 0xe9,0xf9,0xf9,0x10 }, - { 0x04,0x02,0x02,0x06 }, { 0xfe,0x7f,0x7f,0x81 }, - { 0xa0,0x50,0x50,0xf0 }, { 0x78,0x3c,0x3c,0x44 }, - { 0x25,0x9f,0x9f,0xba }, { 0x4b,0xa8,0xa8,0xe3 }, - { 0xa2,0x51,0x51,0xf3 }, { 0x5d,0xa3,0xa3,0xfe }, - { 0x80,0x40,0x40,0xc0 }, { 0x05,0x8f,0x8f,0x8a }, - { 0x3f,0x92,0x92,0xad }, { 0x21,0x9d,0x9d,0xbc }, - { 0x70,0x38,0x38,0x48 }, { 0xf1,0xf5,0xf5,0x04 }, - { 0x63,0xbc,0xbc,0xdf }, { 0x77,0xb6,0xb6,0xc1 }, - { 0xaf,0xda,0xda,0x75 }, { 0x42,0x21,0x21,0x63 }, - { 0x20,0x10,0x10,0x30 }, { 0xe5,0xff,0xff,0x1a }, - { 0xfd,0xf3,0xf3,0x0e }, { 0xbf,0xd2,0xd2,0x6d }, - { 0x81,0xcd,0xcd,0x4c }, { 0x18,0x0c,0x0c,0x14 }, - { 0x26,0x13,0x13,0x35 }, { 0xc3,0xec,0xec,0x2f }, - { 0xbe,0x5f,0x5f,0xe1 }, { 0x35,0x97,0x97,0xa2 }, - { 0x88,0x44,0x44,0xcc }, { 0x2e,0x17,0x17,0x39 }, - { 0x93,0xc4,0xc4,0x57 }, { 0x55,0xa7,0xa7,0xf2 }, - { 0xfc,0x7e,0x7e,0x82 }, { 0x7a,0x3d,0x3d,0x47 }, - { 0xc8,0x64,0x64,0xac }, { 0xba,0x5d,0x5d,0xe7 }, - { 0x32,0x19,0x19,0x2b }, { 0xe6,0x73,0x73,0x95 }, - { 0xc0,0x60,0x60,0xa0 }, { 0x19,0x81,0x81,0x98 }, - { 0x9e,0x4f,0x4f,0xd1 }, { 0xa3,0xdc,0xdc,0x7f }, - { 0x44,0x22,0x22,0x66 }, { 0x54,0x2a,0x2a,0x7e }, - { 0x3b,0x90,0x90,0xab }, { 0x0b,0x88,0x88,0x83 }, - { 0x8c,0x46,0x46,0xca }, { 0xc7,0xee,0xee,0x29 }, - { 0x6b,0xb8,0xb8,0xd3 }, { 0x28,0x14,0x14,0x3c }, - { 0xa7,0xde,0xde,0x79 }, { 0xbc,0x5e,0x5e,0xe2 }, - { 0x16,0x0b,0x0b,0x1d }, { 0xad,0xdb,0xdb,0x76 }, - { 0xdb,0xe0,0xe0,0x3b }, { 0x64,0x32,0x32,0x56 }, - { 0x74,0x3a,0x3a,0x4e }, { 0x14,0x0a,0x0a,0x1e }, - { 0x92,0x49,0x49,0xdb }, { 0x0c,0x06,0x06,0x0a }, - { 0x48,0x24,0x24,0x6c }, { 0xb8,0x5c,0x5c,0xe4 }, - { 0x9f,0xc2,0xc2,0x5d }, { 0xbd,0xd3,0xd3,0x6e }, - { 0x43,0xac,0xac,0xef }, { 0xc4,0x62,0x62,0xa6 }, - { 0x39,0x91,0x91,0xa8 }, { 0x31,0x95,0x95,0xa4 }, - { 0xd3,0xe4,0xe4,0x37 }, { 0xf2,0x79,0x79,0x8b }, - { 0xd5,0xe7,0xe7,0x32 }, { 0x8b,0xc8,0xc8,0x43 }, - { 0x6e,0x37,0x37,0x59 }, { 0xda,0x6d,0x6d,0xb7 }, - { 0x01,0x8d,0x8d,0x8c }, { 0xb1,0xd5,0xd5,0x64 }, - { 0x9c,0x4e,0x4e,0xd2 }, { 0x49,0xa9,0xa9,0xe0 }, - { 0xd8,0x6c,0x6c,0xb4 }, { 0xac,0x56,0x56,0xfa }, - { 0xf3,0xf4,0xf4,0x07 }, { 0xcf,0xea,0xea,0x25 }, - { 0xca,0x65,0x65,0xaf }, { 0xf4,0x7a,0x7a,0x8e }, - { 0x47,0xae,0xae,0xe9 }, { 0x10,0x08,0x08,0x18 }, - { 0x6f,0xba,0xba,0xd5 }, { 0xf0,0x78,0x78,0x88 }, - { 0x4a,0x25,0x25,0x6f }, { 0x5c,0x2e,0x2e,0x72 }, - { 0x38,0x1c,0x1c,0x24 }, { 0x57,0xa6,0xa6,0xf1 }, - { 0x73,0xb4,0xb4,0xc7 }, { 0x97,0xc6,0xc6,0x51 }, - { 0xcb,0xe8,0xe8,0x23 }, { 0xa1,0xdd,0xdd,0x7c }, - { 0xe8,0x74,0x74,0x9c }, { 0x3e,0x1f,0x1f,0x21 }, - { 0x96,0x4b,0x4b,0xdd }, { 0x61,0xbd,0xbd,0xdc }, - { 0x0d,0x8b,0x8b,0x86 }, { 0x0f,0x8a,0x8a,0x85 }, - { 0xe0,0x70,0x70,0x90 }, { 0x7c,0x3e,0x3e,0x42 }, - { 0x71,0xb5,0xb5,0xc4 }, { 0xcc,0x66,0x66,0xaa }, - { 0x90,0x48,0x48,0xd8 }, { 0x06,0x03,0x03,0x05 }, - { 0xf7,0xf6,0xf6,0x01 }, { 0x1c,0x0e,0x0e,0x12 }, - { 0xc2,0x61,0x61,0xa3 }, { 0x6a,0x35,0x35,0x5f }, - { 0xae,0x57,0x57,0xf9 }, { 0x69,0xb9,0xb9,0xd0 }, - { 0x17,0x86,0x86,0x91 }, { 0x99,0xc1,0xc1,0x58 }, - { 0x3a,0x1d,0x1d,0x27 }, { 0x27,0x9e,0x9e,0xb9 }, - { 0xd9,0xe1,0xe1,0x38 }, { 0xeb,0xf8,0xf8,0x13 }, - { 0x2b,0x98,0x98,0xb3 }, { 0x22,0x11,0x11,0x33 }, - { 0xd2,0x69,0x69,0xbb }, { 0xa9,0xd9,0xd9,0x70 }, - { 0x07,0x8e,0x8e,0x89 }, { 0x33,0x94,0x94,0xa7 }, - { 0x2d,0x9b,0x9b,0xb6 }, { 0x3c,0x1e,0x1e,0x22 }, - { 0x15,0x87,0x87,0x92 }, { 0xc9,0xe9,0xe9,0x20 }, - { 0x87,0xce,0xce,0x49 }, { 0xaa,0x55,0x55,0xff }, - { 0x50,0x28,0x28,0x78 }, { 0xa5,0xdf,0xdf,0x7a }, - { 0x03,0x8c,0x8c,0x8f }, { 0x59,0xa1,0xa1,0xf8 }, - { 0x09,0x89,0x89,0x80 }, { 0x1a,0x0d,0x0d,0x17 }, - { 0x65,0xbf,0xbf,0xda }, { 0xd7,0xe6,0xe6,0x31 }, - { 0x84,0x42,0x42,0xc6 }, { 0xd0,0x68,0x68,0xb8 }, - { 0x82,0x41,0x41,0xc3 }, { 0x29,0x99,0x99,0xb0 }, - { 0x5a,0x2d,0x2d,0x77 }, { 0x1e,0x0f,0x0f,0x11 }, - { 0x7b,0xb0,0xb0,0xcb }, { 0xa8,0x54,0x54,0xfc }, - { 0x6d,0xbb,0xbb,0xd6 }, { 0x2c,0x16,0x16,0x3a } - }; - -static const unsigned char T2[256][4] = - { - { 0xa5,0xc6,0x63,0x63 }, { 0x84,0xf8,0x7c,0x7c }, - { 0x99,0xee,0x77,0x77 }, { 0x8d,0xf6,0x7b,0x7b }, - { 0x0d,0xff,0xf2,0xf2 }, { 0xbd,0xd6,0x6b,0x6b }, - { 0xb1,0xde,0x6f,0x6f }, { 0x54,0x91,0xc5,0xc5 }, - { 0x50,0x60,0x30,0x30 }, { 0x03,0x02,0x01,0x01 }, - { 0xa9,0xce,0x67,0x67 }, { 0x7d,0x56,0x2b,0x2b }, - { 0x19,0xe7,0xfe,0xfe }, { 0x62,0xb5,0xd7,0xd7 }, - { 0xe6,0x4d,0xab,0xab }, { 0x9a,0xec,0x76,0x76 }, - { 0x45,0x8f,0xca,0xca }, { 0x9d,0x1f,0x82,0x82 }, - { 0x40,0x89,0xc9,0xc9 }, { 0x87,0xfa,0x7d,0x7d }, - { 0x15,0xef,0xfa,0xfa }, { 0xeb,0xb2,0x59,0x59 }, - { 0xc9,0x8e,0x47,0x47 }, { 0x0b,0xfb,0xf0,0xf0 }, - { 0xec,0x41,0xad,0xad }, { 0x67,0xb3,0xd4,0xd4 }, - { 0xfd,0x5f,0xa2,0xa2 }, { 0xea,0x45,0xaf,0xaf }, - { 0xbf,0x23,0x9c,0x9c }, { 0xf7,0x53,0xa4,0xa4 }, - { 0x96,0xe4,0x72,0x72 }, { 0x5b,0x9b,0xc0,0xc0 }, - { 0xc2,0x75,0xb7,0xb7 }, { 0x1c,0xe1,0xfd,0xfd }, - { 0xae,0x3d,0x93,0x93 }, { 0x6a,0x4c,0x26,0x26 }, - { 0x5a,0x6c,0x36,0x36 }, { 0x41,0x7e,0x3f,0x3f }, - { 0x02,0xf5,0xf7,0xf7 }, { 0x4f,0x83,0xcc,0xcc }, - { 0x5c,0x68,0x34,0x34 }, { 0xf4,0x51,0xa5,0xa5 }, - { 0x34,0xd1,0xe5,0xe5 }, { 0x08,0xf9,0xf1,0xf1 }, - { 0x93,0xe2,0x71,0x71 }, { 0x73,0xab,0xd8,0xd8 }, - { 0x53,0x62,0x31,0x31 }, { 0x3f,0x2a,0x15,0x15 }, - { 0x0c,0x08,0x04,0x04 }, { 0x52,0x95,0xc7,0xc7 }, - { 0x65,0x46,0x23,0x23 }, { 0x5e,0x9d,0xc3,0xc3 }, - { 0x28,0x30,0x18,0x18 }, { 0xa1,0x37,0x96,0x96 }, - { 0x0f,0x0a,0x05,0x05 }, { 0xb5,0x2f,0x9a,0x9a }, - { 0x09,0x0e,0x07,0x07 }, { 0x36,0x24,0x12,0x12 }, - { 0x9b,0x1b,0x80,0x80 }, { 0x3d,0xdf,0xe2,0xe2 }, - { 0x26,0xcd,0xeb,0xeb }, { 0x69,0x4e,0x27,0x27 }, - { 0xcd,0x7f,0xb2,0xb2 }, { 0x9f,0xea,0x75,0x75 }, - { 0x1b,0x12,0x09,0x09 }, { 0x9e,0x1d,0x83,0x83 }, - { 0x74,0x58,0x2c,0x2c }, { 0x2e,0x34,0x1a,0x1a }, - { 0x2d,0x36,0x1b,0x1b }, { 0xb2,0xdc,0x6e,0x6e }, - { 0xee,0xb4,0x5a,0x5a }, { 0xfb,0x5b,0xa0,0xa0 }, - { 0xf6,0xa4,0x52,0x52 }, { 0x4d,0x76,0x3b,0x3b }, - { 0x61,0xb7,0xd6,0xd6 }, { 0xce,0x7d,0xb3,0xb3 }, - { 0x7b,0x52,0x29,0x29 }, { 0x3e,0xdd,0xe3,0xe3 }, - { 0x71,0x5e,0x2f,0x2f }, { 0x97,0x13,0x84,0x84 }, - { 0xf5,0xa6,0x53,0x53 }, { 0x68,0xb9,0xd1,0xd1 }, - { 0x00,0x00,0x00,0x00 }, { 0x2c,0xc1,0xed,0xed }, - { 0x60,0x40,0x20,0x20 }, { 0x1f,0xe3,0xfc,0xfc }, - { 0xc8,0x79,0xb1,0xb1 }, { 0xed,0xb6,0x5b,0x5b }, - { 0xbe,0xd4,0x6a,0x6a }, { 0x46,0x8d,0xcb,0xcb }, - { 0xd9,0x67,0xbe,0xbe }, { 0x4b,0x72,0x39,0x39 }, - { 0xde,0x94,0x4a,0x4a }, { 0xd4,0x98,0x4c,0x4c }, - { 0xe8,0xb0,0x58,0x58 }, { 0x4a,0x85,0xcf,0xcf }, - { 0x6b,0xbb,0xd0,0xd0 }, { 0x2a,0xc5,0xef,0xef }, - { 0xe5,0x4f,0xaa,0xaa }, { 0x16,0xed,0xfb,0xfb }, - { 0xc5,0x86,0x43,0x43 }, { 0xd7,0x9a,0x4d,0x4d }, - { 0x55,0x66,0x33,0x33 }, { 0x94,0x11,0x85,0x85 }, - { 0xcf,0x8a,0x45,0x45 }, { 0x10,0xe9,0xf9,0xf9 }, - { 0x06,0x04,0x02,0x02 }, { 0x81,0xfe,0x7f,0x7f }, - { 0xf0,0xa0,0x50,0x50 }, { 0x44,0x78,0x3c,0x3c }, - { 0xba,0x25,0x9f,0x9f }, { 0xe3,0x4b,0xa8,0xa8 }, - { 0xf3,0xa2,0x51,0x51 }, { 0xfe,0x5d,0xa3,0xa3 }, - { 0xc0,0x80,0x40,0x40 }, { 0x8a,0x05,0x8f,0x8f }, - { 0xad,0x3f,0x92,0x92 }, { 0xbc,0x21,0x9d,0x9d }, - { 0x48,0x70,0x38,0x38 }, { 0x04,0xf1,0xf5,0xf5 }, - { 0xdf,0x63,0xbc,0xbc }, { 0xc1,0x77,0xb6,0xb6 }, - { 0x75,0xaf,0xda,0xda }, { 0x63,0x42,0x21,0x21 }, - { 0x30,0x20,0x10,0x10 }, { 0x1a,0xe5,0xff,0xff }, - { 0x0e,0xfd,0xf3,0xf3 }, { 0x6d,0xbf,0xd2,0xd2 }, - { 0x4c,0x81,0xcd,0xcd }, { 0x14,0x18,0x0c,0x0c }, - { 0x35,0x26,0x13,0x13 }, { 0x2f,0xc3,0xec,0xec }, - { 0xe1,0xbe,0x5f,0x5f }, { 0xa2,0x35,0x97,0x97 }, - { 0xcc,0x88,0x44,0x44 }, { 0x39,0x2e,0x17,0x17 }, - { 0x57,0x93,0xc4,0xc4 }, { 0xf2,0x55,0xa7,0xa7 }, - { 0x82,0xfc,0x7e,0x7e }, { 0x47,0x7a,0x3d,0x3d }, - { 0xac,0xc8,0x64,0x64 }, { 0xe7,0xba,0x5d,0x5d }, - { 0x2b,0x32,0x19,0x19 }, { 0x95,0xe6,0x73,0x73 }, - { 0xa0,0xc0,0x60,0x60 }, { 0x98,0x19,0x81,0x81 }, - { 0xd1,0x9e,0x4f,0x4f }, { 0x7f,0xa3,0xdc,0xdc }, - { 0x66,0x44,0x22,0x22 }, { 0x7e,0x54,0x2a,0x2a }, - { 0xab,0x3b,0x90,0x90 }, { 0x83,0x0b,0x88,0x88 }, - { 0xca,0x8c,0x46,0x46 }, { 0x29,0xc7,0xee,0xee }, - { 0xd3,0x6b,0xb8,0xb8 }, { 0x3c,0x28,0x14,0x14 }, - { 0x79,0xa7,0xde,0xde }, { 0xe2,0xbc,0x5e,0x5e }, - { 0x1d,0x16,0x0b,0x0b }, { 0x76,0xad,0xdb,0xdb }, - { 0x3b,0xdb,0xe0,0xe0 }, { 0x56,0x64,0x32,0x32 }, - { 0x4e,0x74,0x3a,0x3a }, { 0x1e,0x14,0x0a,0x0a }, - { 0xdb,0x92,0x49,0x49 }, { 0x0a,0x0c,0x06,0x06 }, - { 0x6c,0x48,0x24,0x24 }, { 0xe4,0xb8,0x5c,0x5c }, - { 0x5d,0x9f,0xc2,0xc2 }, { 0x6e,0xbd,0xd3,0xd3 }, - { 0xef,0x43,0xac,0xac }, { 0xa6,0xc4,0x62,0x62 }, - { 0xa8,0x39,0x91,0x91 }, { 0xa4,0x31,0x95,0x95 }, - { 0x37,0xd3,0xe4,0xe4 }, { 0x8b,0xf2,0x79,0x79 }, - { 0x32,0xd5,0xe7,0xe7 }, { 0x43,0x8b,0xc8,0xc8 }, - { 0x59,0x6e,0x37,0x37 }, { 0xb7,0xda,0x6d,0x6d }, - { 0x8c,0x01,0x8d,0x8d }, { 0x64,0xb1,0xd5,0xd5 }, - { 0xd2,0x9c,0x4e,0x4e }, { 0xe0,0x49,0xa9,0xa9 }, - { 0xb4,0xd8,0x6c,0x6c }, { 0xfa,0xac,0x56,0x56 }, - { 0x07,0xf3,0xf4,0xf4 }, { 0x25,0xcf,0xea,0xea }, - { 0xaf,0xca,0x65,0x65 }, { 0x8e,0xf4,0x7a,0x7a }, - { 0xe9,0x47,0xae,0xae }, { 0x18,0x10,0x08,0x08 }, - { 0xd5,0x6f,0xba,0xba }, { 0x88,0xf0,0x78,0x78 }, - { 0x6f,0x4a,0x25,0x25 }, { 0x72,0x5c,0x2e,0x2e }, - { 0x24,0x38,0x1c,0x1c }, { 0xf1,0x57,0xa6,0xa6 }, - { 0xc7,0x73,0xb4,0xb4 }, { 0x51,0x97,0xc6,0xc6 }, - { 0x23,0xcb,0xe8,0xe8 }, { 0x7c,0xa1,0xdd,0xdd }, - { 0x9c,0xe8,0x74,0x74 }, { 0x21,0x3e,0x1f,0x1f }, - { 0xdd,0x96,0x4b,0x4b }, { 0xdc,0x61,0xbd,0xbd }, - { 0x86,0x0d,0x8b,0x8b }, { 0x85,0x0f,0x8a,0x8a }, - { 0x90,0xe0,0x70,0x70 }, { 0x42,0x7c,0x3e,0x3e }, - { 0xc4,0x71,0xb5,0xb5 }, { 0xaa,0xcc,0x66,0x66 }, - { 0xd8,0x90,0x48,0x48 }, { 0x05,0x06,0x03,0x03 }, - { 0x01,0xf7,0xf6,0xf6 }, { 0x12,0x1c,0x0e,0x0e }, - { 0xa3,0xc2,0x61,0x61 }, { 0x5f,0x6a,0x35,0x35 }, - { 0xf9,0xae,0x57,0x57 }, { 0xd0,0x69,0xb9,0xb9 }, - { 0x91,0x17,0x86,0x86 }, { 0x58,0x99,0xc1,0xc1 }, - { 0x27,0x3a,0x1d,0x1d }, { 0xb9,0x27,0x9e,0x9e }, - { 0x38,0xd9,0xe1,0xe1 }, { 0x13,0xeb,0xf8,0xf8 }, - { 0xb3,0x2b,0x98,0x98 }, { 0x33,0x22,0x11,0x11 }, - { 0xbb,0xd2,0x69,0x69 }, { 0x70,0xa9,0xd9,0xd9 }, - { 0x89,0x07,0x8e,0x8e }, { 0xa7,0x33,0x94,0x94 }, - { 0xb6,0x2d,0x9b,0x9b }, { 0x22,0x3c,0x1e,0x1e }, - { 0x92,0x15,0x87,0x87 }, { 0x20,0xc9,0xe9,0xe9 }, - { 0x49,0x87,0xce,0xce }, { 0xff,0xaa,0x55,0x55 }, - { 0x78,0x50,0x28,0x28 }, { 0x7a,0xa5,0xdf,0xdf }, - { 0x8f,0x03,0x8c,0x8c }, { 0xf8,0x59,0xa1,0xa1 }, - { 0x80,0x09,0x89,0x89 }, { 0x17,0x1a,0x0d,0x0d }, - { 0xda,0x65,0xbf,0xbf }, { 0x31,0xd7,0xe6,0xe6 }, - { 0xc6,0x84,0x42,0x42 }, { 0xb8,0xd0,0x68,0x68 }, - { 0xc3,0x82,0x41,0x41 }, { 0xb0,0x29,0x99,0x99 }, - { 0x77,0x5a,0x2d,0x2d }, { 0x11,0x1e,0x0f,0x0f }, - { 0xcb,0x7b,0xb0,0xb0 }, { 0xfc,0xa8,0x54,0x54 }, - { 0xd6,0x6d,0xbb,0xbb }, { 0x3a,0x2c,0x16,0x16 } - }; - -static const unsigned char T3[256][4] = - { - { 0x63,0xa5,0xc6,0x63 }, { 0x7c,0x84,0xf8,0x7c }, - { 0x77,0x99,0xee,0x77 }, { 0x7b,0x8d,0xf6,0x7b }, - { 0xf2,0x0d,0xff,0xf2 }, { 0x6b,0xbd,0xd6,0x6b }, - { 0x6f,0xb1,0xde,0x6f }, { 0xc5,0x54,0x91,0xc5 }, - { 0x30,0x50,0x60,0x30 }, { 0x01,0x03,0x02,0x01 }, - { 0x67,0xa9,0xce,0x67 }, { 0x2b,0x7d,0x56,0x2b }, - { 0xfe,0x19,0xe7,0xfe }, { 0xd7,0x62,0xb5,0xd7 }, - { 0xab,0xe6,0x4d,0xab }, { 0x76,0x9a,0xec,0x76 }, - { 0xca,0x45,0x8f,0xca }, { 0x82,0x9d,0x1f,0x82 }, - { 0xc9,0x40,0x89,0xc9 }, { 0x7d,0x87,0xfa,0x7d }, - { 0xfa,0x15,0xef,0xfa }, { 0x59,0xeb,0xb2,0x59 }, - { 0x47,0xc9,0x8e,0x47 }, { 0xf0,0x0b,0xfb,0xf0 }, - { 0xad,0xec,0x41,0xad }, { 0xd4,0x67,0xb3,0xd4 }, - { 0xa2,0xfd,0x5f,0xa2 }, { 0xaf,0xea,0x45,0xaf }, - { 0x9c,0xbf,0x23,0x9c }, { 0xa4,0xf7,0x53,0xa4 }, - { 0x72,0x96,0xe4,0x72 }, { 0xc0,0x5b,0x9b,0xc0 }, - { 0xb7,0xc2,0x75,0xb7 }, { 0xfd,0x1c,0xe1,0xfd }, - { 0x93,0xae,0x3d,0x93 }, { 0x26,0x6a,0x4c,0x26 }, - { 0x36,0x5a,0x6c,0x36 }, { 0x3f,0x41,0x7e,0x3f }, - { 0xf7,0x02,0xf5,0xf7 }, { 0xcc,0x4f,0x83,0xcc }, - { 0x34,0x5c,0x68,0x34 }, { 0xa5,0xf4,0x51,0xa5 }, - { 0xe5,0x34,0xd1,0xe5 }, { 0xf1,0x08,0xf9,0xf1 }, - { 0x71,0x93,0xe2,0x71 }, { 0xd8,0x73,0xab,0xd8 }, - { 0x31,0x53,0x62,0x31 }, { 0x15,0x3f,0x2a,0x15 }, - { 0x04,0x0c,0x08,0x04 }, { 0xc7,0x52,0x95,0xc7 }, - { 0x23,0x65,0x46,0x23 }, { 0xc3,0x5e,0x9d,0xc3 }, - { 0x18,0x28,0x30,0x18 }, { 0x96,0xa1,0x37,0x96 }, - { 0x05,0x0f,0x0a,0x05 }, { 0x9a,0xb5,0x2f,0x9a }, - { 0x07,0x09,0x0e,0x07 }, { 0x12,0x36,0x24,0x12 }, - { 0x80,0x9b,0x1b,0x80 }, { 0xe2,0x3d,0xdf,0xe2 }, - { 0xeb,0x26,0xcd,0xeb }, { 0x27,0x69,0x4e,0x27 }, - { 0xb2,0xcd,0x7f,0xb2 }, { 0x75,0x9f,0xea,0x75 }, - { 0x09,0x1b,0x12,0x09 }, { 0x83,0x9e,0x1d,0x83 }, - { 0x2c,0x74,0x58,0x2c }, { 0x1a,0x2e,0x34,0x1a }, - { 0x1b,0x2d,0x36,0x1b }, { 0x6e,0xb2,0xdc,0x6e }, - { 0x5a,0xee,0xb4,0x5a }, { 0xa0,0xfb,0x5b,0xa0 }, - { 0x52,0xf6,0xa4,0x52 }, { 0x3b,0x4d,0x76,0x3b }, - { 0xd6,0x61,0xb7,0xd6 }, { 0xb3,0xce,0x7d,0xb3 }, - { 0x29,0x7b,0x52,0x29 }, { 0xe3,0x3e,0xdd,0xe3 }, - { 0x2f,0x71,0x5e,0x2f }, { 0x84,0x97,0x13,0x84 }, - { 0x53,0xf5,0xa6,0x53 }, { 0xd1,0x68,0xb9,0xd1 }, - { 0x00,0x00,0x00,0x00 }, { 0xed,0x2c,0xc1,0xed }, - { 0x20,0x60,0x40,0x20 }, { 0xfc,0x1f,0xe3,0xfc }, - { 0xb1,0xc8,0x79,0xb1 }, { 0x5b,0xed,0xb6,0x5b }, - { 0x6a,0xbe,0xd4,0x6a }, { 0xcb,0x46,0x8d,0xcb }, - { 0xbe,0xd9,0x67,0xbe }, { 0x39,0x4b,0x72,0x39 }, - { 0x4a,0xde,0x94,0x4a }, { 0x4c,0xd4,0x98,0x4c }, - { 0x58,0xe8,0xb0,0x58 }, { 0xcf,0x4a,0x85,0xcf }, - { 0xd0,0x6b,0xbb,0xd0 }, { 0xef,0x2a,0xc5,0xef }, - { 0xaa,0xe5,0x4f,0xaa }, { 0xfb,0x16,0xed,0xfb }, - { 0x43,0xc5,0x86,0x43 }, { 0x4d,0xd7,0x9a,0x4d }, - { 0x33,0x55,0x66,0x33 }, { 0x85,0x94,0x11,0x85 }, - { 0x45,0xcf,0x8a,0x45 }, { 0xf9,0x10,0xe9,0xf9 }, - { 0x02,0x06,0x04,0x02 }, { 0x7f,0x81,0xfe,0x7f }, - { 0x50,0xf0,0xa0,0x50 }, { 0x3c,0x44,0x78,0x3c }, - { 0x9f,0xba,0x25,0x9f }, { 0xa8,0xe3,0x4b,0xa8 }, - { 0x51,0xf3,0xa2,0x51 }, { 0xa3,0xfe,0x5d,0xa3 }, - { 0x40,0xc0,0x80,0x40 }, { 0x8f,0x8a,0x05,0x8f }, - { 0x92,0xad,0x3f,0x92 }, { 0x9d,0xbc,0x21,0x9d }, - { 0x38,0x48,0x70,0x38 }, { 0xf5,0x04,0xf1,0xf5 }, - { 0xbc,0xdf,0x63,0xbc }, { 0xb6,0xc1,0x77,0xb6 }, - { 0xda,0x75,0xaf,0xda }, { 0x21,0x63,0x42,0x21 }, - { 0x10,0x30,0x20,0x10 }, { 0xff,0x1a,0xe5,0xff }, - { 0xf3,0x0e,0xfd,0xf3 }, { 0xd2,0x6d,0xbf,0xd2 }, - { 0xcd,0x4c,0x81,0xcd }, { 0x0c,0x14,0x18,0x0c }, - { 0x13,0x35,0x26,0x13 }, { 0xec,0x2f,0xc3,0xec }, - { 0x5f,0xe1,0xbe,0x5f }, { 0x97,0xa2,0x35,0x97 }, - { 0x44,0xcc,0x88,0x44 }, { 0x17,0x39,0x2e,0x17 }, - { 0xc4,0x57,0x93,0xc4 }, { 0xa7,0xf2,0x55,0xa7 }, - { 0x7e,0x82,0xfc,0x7e }, { 0x3d,0x47,0x7a,0x3d }, - { 0x64,0xac,0xc8,0x64 }, { 0x5d,0xe7,0xba,0x5d }, - { 0x19,0x2b,0x32,0x19 }, { 0x73,0x95,0xe6,0x73 }, - { 0x60,0xa0,0xc0,0x60 }, { 0x81,0x98,0x19,0x81 }, - { 0x4f,0xd1,0x9e,0x4f }, { 0xdc,0x7f,0xa3,0xdc }, - { 0x22,0x66,0x44,0x22 }, { 0x2a,0x7e,0x54,0x2a }, - { 0x90,0xab,0x3b,0x90 }, { 0x88,0x83,0x0b,0x88 }, - { 0x46,0xca,0x8c,0x46 }, { 0xee,0x29,0xc7,0xee }, - { 0xb8,0xd3,0x6b,0xb8 }, { 0x14,0x3c,0x28,0x14 }, - { 0xde,0x79,0xa7,0xde }, { 0x5e,0xe2,0xbc,0x5e }, - { 0x0b,0x1d,0x16,0x0b }, { 0xdb,0x76,0xad,0xdb }, - { 0xe0,0x3b,0xdb,0xe0 }, { 0x32,0x56,0x64,0x32 }, - { 0x3a,0x4e,0x74,0x3a }, { 0x0a,0x1e,0x14,0x0a }, - { 0x49,0xdb,0x92,0x49 }, { 0x06,0x0a,0x0c,0x06 }, - { 0x24,0x6c,0x48,0x24 }, { 0x5c,0xe4,0xb8,0x5c }, - { 0xc2,0x5d,0x9f,0xc2 }, { 0xd3,0x6e,0xbd,0xd3 }, - { 0xac,0xef,0x43,0xac }, { 0x62,0xa6,0xc4,0x62 }, - { 0x91,0xa8,0x39,0x91 }, { 0x95,0xa4,0x31,0x95 }, - { 0xe4,0x37,0xd3,0xe4 }, { 0x79,0x8b,0xf2,0x79 }, - { 0xe7,0x32,0xd5,0xe7 }, { 0xc8,0x43,0x8b,0xc8 }, - { 0x37,0x59,0x6e,0x37 }, { 0x6d,0xb7,0xda,0x6d }, - { 0x8d,0x8c,0x01,0x8d }, { 0xd5,0x64,0xb1,0xd5 }, - { 0x4e,0xd2,0x9c,0x4e }, { 0xa9,0xe0,0x49,0xa9 }, - { 0x6c,0xb4,0xd8,0x6c }, { 0x56,0xfa,0xac,0x56 }, - { 0xf4,0x07,0xf3,0xf4 }, { 0xea,0x25,0xcf,0xea }, - { 0x65,0xaf,0xca,0x65 }, { 0x7a,0x8e,0xf4,0x7a }, - { 0xae,0xe9,0x47,0xae }, { 0x08,0x18,0x10,0x08 }, - { 0xba,0xd5,0x6f,0xba }, { 0x78,0x88,0xf0,0x78 }, - { 0x25,0x6f,0x4a,0x25 }, { 0x2e,0x72,0x5c,0x2e }, - { 0x1c,0x24,0x38,0x1c }, { 0xa6,0xf1,0x57,0xa6 }, - { 0xb4,0xc7,0x73,0xb4 }, { 0xc6,0x51,0x97,0xc6 }, - { 0xe8,0x23,0xcb,0xe8 }, { 0xdd,0x7c,0xa1,0xdd }, - { 0x74,0x9c,0xe8,0x74 }, { 0x1f,0x21,0x3e,0x1f }, - { 0x4b,0xdd,0x96,0x4b }, { 0xbd,0xdc,0x61,0xbd }, - { 0x8b,0x86,0x0d,0x8b }, { 0x8a,0x85,0x0f,0x8a }, - { 0x70,0x90,0xe0,0x70 }, { 0x3e,0x42,0x7c,0x3e }, - { 0xb5,0xc4,0x71,0xb5 }, { 0x66,0xaa,0xcc,0x66 }, - { 0x48,0xd8,0x90,0x48 }, { 0x03,0x05,0x06,0x03 }, - { 0xf6,0x01,0xf7,0xf6 }, { 0x0e,0x12,0x1c,0x0e }, - { 0x61,0xa3,0xc2,0x61 }, { 0x35,0x5f,0x6a,0x35 }, - { 0x57,0xf9,0xae,0x57 }, { 0xb9,0xd0,0x69,0xb9 }, - { 0x86,0x91,0x17,0x86 }, { 0xc1,0x58,0x99,0xc1 }, - { 0x1d,0x27,0x3a,0x1d }, { 0x9e,0xb9,0x27,0x9e }, - { 0xe1,0x38,0xd9,0xe1 }, { 0xf8,0x13,0xeb,0xf8 }, - { 0x98,0xb3,0x2b,0x98 }, { 0x11,0x33,0x22,0x11 }, - { 0x69,0xbb,0xd2,0x69 }, { 0xd9,0x70,0xa9,0xd9 }, - { 0x8e,0x89,0x07,0x8e }, { 0x94,0xa7,0x33,0x94 }, - { 0x9b,0xb6,0x2d,0x9b }, { 0x1e,0x22,0x3c,0x1e }, - { 0x87,0x92,0x15,0x87 }, { 0xe9,0x20,0xc9,0xe9 }, - { 0xce,0x49,0x87,0xce }, { 0x55,0xff,0xaa,0x55 }, - { 0x28,0x78,0x50,0x28 }, { 0xdf,0x7a,0xa5,0xdf }, - { 0x8c,0x8f,0x03,0x8c }, { 0xa1,0xf8,0x59,0xa1 }, - { 0x89,0x80,0x09,0x89 }, { 0x0d,0x17,0x1a,0x0d }, - { 0xbf,0xda,0x65,0xbf }, { 0xe6,0x31,0xd7,0xe6 }, - { 0x42,0xc6,0x84,0x42 }, { 0x68,0xb8,0xd0,0x68 }, - { 0x41,0xc3,0x82,0x41 }, { 0x99,0xb0,0x29,0x99 }, - { 0x2d,0x77,0x5a,0x2d }, { 0x0f,0x11,0x1e,0x0f }, - { 0xb0,0xcb,0x7b,0xb0 }, { 0x54,0xfc,0xa8,0x54 }, - { 0xbb,0xd6,0x6d,0xbb }, { 0x16,0x3a,0x2c,0x16 } - }; - -static const unsigned char T4[256][4] = - { - { 0x63,0x63,0xa5,0xc6 }, { 0x7c,0x7c,0x84,0xf8 }, - { 0x77,0x77,0x99,0xee }, { 0x7b,0x7b,0x8d,0xf6 }, - { 0xf2,0xf2,0x0d,0xff }, { 0x6b,0x6b,0xbd,0xd6 }, - { 0x6f,0x6f,0xb1,0xde }, { 0xc5,0xc5,0x54,0x91 }, - { 0x30,0x30,0x50,0x60 }, { 0x01,0x01,0x03,0x02 }, - { 0x67,0x67,0xa9,0xce }, { 0x2b,0x2b,0x7d,0x56 }, - { 0xfe,0xfe,0x19,0xe7 }, { 0xd7,0xd7,0x62,0xb5 }, - { 0xab,0xab,0xe6,0x4d }, { 0x76,0x76,0x9a,0xec }, - { 0xca,0xca,0x45,0x8f }, { 0x82,0x82,0x9d,0x1f }, - { 0xc9,0xc9,0x40,0x89 }, { 0x7d,0x7d,0x87,0xfa }, - { 0xfa,0xfa,0x15,0xef }, { 0x59,0x59,0xeb,0xb2 }, - { 0x47,0x47,0xc9,0x8e }, { 0xf0,0xf0,0x0b,0xfb }, - { 0xad,0xad,0xec,0x41 }, { 0xd4,0xd4,0x67,0xb3 }, - { 0xa2,0xa2,0xfd,0x5f }, { 0xaf,0xaf,0xea,0x45 }, - { 0x9c,0x9c,0xbf,0x23 }, { 0xa4,0xa4,0xf7,0x53 }, - { 0x72,0x72,0x96,0xe4 }, { 0xc0,0xc0,0x5b,0x9b }, - { 0xb7,0xb7,0xc2,0x75 }, { 0xfd,0xfd,0x1c,0xe1 }, - { 0x93,0x93,0xae,0x3d }, { 0x26,0x26,0x6a,0x4c }, - { 0x36,0x36,0x5a,0x6c }, { 0x3f,0x3f,0x41,0x7e }, - { 0xf7,0xf7,0x02,0xf5 }, { 0xcc,0xcc,0x4f,0x83 }, - { 0x34,0x34,0x5c,0x68 }, { 0xa5,0xa5,0xf4,0x51 }, - { 0xe5,0xe5,0x34,0xd1 }, { 0xf1,0xf1,0x08,0xf9 }, - { 0x71,0x71,0x93,0xe2 }, { 0xd8,0xd8,0x73,0xab }, - { 0x31,0x31,0x53,0x62 }, { 0x15,0x15,0x3f,0x2a }, - { 0x04,0x04,0x0c,0x08 }, { 0xc7,0xc7,0x52,0x95 }, - { 0x23,0x23,0x65,0x46 }, { 0xc3,0xc3,0x5e,0x9d }, - { 0x18,0x18,0x28,0x30 }, { 0x96,0x96,0xa1,0x37 }, - { 0x05,0x05,0x0f,0x0a }, { 0x9a,0x9a,0xb5,0x2f }, - { 0x07,0x07,0x09,0x0e }, { 0x12,0x12,0x36,0x24 }, - { 0x80,0x80,0x9b,0x1b }, { 0xe2,0xe2,0x3d,0xdf }, - { 0xeb,0xeb,0x26,0xcd }, { 0x27,0x27,0x69,0x4e }, - { 0xb2,0xb2,0xcd,0x7f }, { 0x75,0x75,0x9f,0xea }, - { 0x09,0x09,0x1b,0x12 }, { 0x83,0x83,0x9e,0x1d }, - { 0x2c,0x2c,0x74,0x58 }, { 0x1a,0x1a,0x2e,0x34 }, - { 0x1b,0x1b,0x2d,0x36 }, { 0x6e,0x6e,0xb2,0xdc }, - { 0x5a,0x5a,0xee,0xb4 }, { 0xa0,0xa0,0xfb,0x5b }, - { 0x52,0x52,0xf6,0xa4 }, { 0x3b,0x3b,0x4d,0x76 }, - { 0xd6,0xd6,0x61,0xb7 }, { 0xb3,0xb3,0xce,0x7d }, - { 0x29,0x29,0x7b,0x52 }, { 0xe3,0xe3,0x3e,0xdd }, - { 0x2f,0x2f,0x71,0x5e }, { 0x84,0x84,0x97,0x13 }, - { 0x53,0x53,0xf5,0xa6 }, { 0xd1,0xd1,0x68,0xb9 }, - { 0x00,0x00,0x00,0x00 }, { 0xed,0xed,0x2c,0xc1 }, - { 0x20,0x20,0x60,0x40 }, { 0xfc,0xfc,0x1f,0xe3 }, - { 0xb1,0xb1,0xc8,0x79 }, { 0x5b,0x5b,0xed,0xb6 }, - { 0x6a,0x6a,0xbe,0xd4 }, { 0xcb,0xcb,0x46,0x8d }, - { 0xbe,0xbe,0xd9,0x67 }, { 0x39,0x39,0x4b,0x72 }, - { 0x4a,0x4a,0xde,0x94 }, { 0x4c,0x4c,0xd4,0x98 }, - { 0x58,0x58,0xe8,0xb0 }, { 0xcf,0xcf,0x4a,0x85 }, - { 0xd0,0xd0,0x6b,0xbb }, { 0xef,0xef,0x2a,0xc5 }, - { 0xaa,0xaa,0xe5,0x4f }, { 0xfb,0xfb,0x16,0xed }, - { 0x43,0x43,0xc5,0x86 }, { 0x4d,0x4d,0xd7,0x9a }, - { 0x33,0x33,0x55,0x66 }, { 0x85,0x85,0x94,0x11 }, - { 0x45,0x45,0xcf,0x8a }, { 0xf9,0xf9,0x10,0xe9 }, - { 0x02,0x02,0x06,0x04 }, { 0x7f,0x7f,0x81,0xfe }, - { 0x50,0x50,0xf0,0xa0 }, { 0x3c,0x3c,0x44,0x78 }, - { 0x9f,0x9f,0xba,0x25 }, { 0xa8,0xa8,0xe3,0x4b }, - { 0x51,0x51,0xf3,0xa2 }, { 0xa3,0xa3,0xfe,0x5d }, - { 0x40,0x40,0xc0,0x80 }, { 0x8f,0x8f,0x8a,0x05 }, - { 0x92,0x92,0xad,0x3f }, { 0x9d,0x9d,0xbc,0x21 }, - { 0x38,0x38,0x48,0x70 }, { 0xf5,0xf5,0x04,0xf1 }, - { 0xbc,0xbc,0xdf,0x63 }, { 0xb6,0xb6,0xc1,0x77 }, - { 0xda,0xda,0x75,0xaf }, { 0x21,0x21,0x63,0x42 }, - { 0x10,0x10,0x30,0x20 }, { 0xff,0xff,0x1a,0xe5 }, - { 0xf3,0xf3,0x0e,0xfd }, { 0xd2,0xd2,0x6d,0xbf }, - { 0xcd,0xcd,0x4c,0x81 }, { 0x0c,0x0c,0x14,0x18 }, - { 0x13,0x13,0x35,0x26 }, { 0xec,0xec,0x2f,0xc3 }, - { 0x5f,0x5f,0xe1,0xbe }, { 0x97,0x97,0xa2,0x35 }, - { 0x44,0x44,0xcc,0x88 }, { 0x17,0x17,0x39,0x2e }, - { 0xc4,0xc4,0x57,0x93 }, { 0xa7,0xa7,0xf2,0x55 }, - { 0x7e,0x7e,0x82,0xfc }, { 0x3d,0x3d,0x47,0x7a }, - { 0x64,0x64,0xac,0xc8 }, { 0x5d,0x5d,0xe7,0xba }, - { 0x19,0x19,0x2b,0x32 }, { 0x73,0x73,0x95,0xe6 }, - { 0x60,0x60,0xa0,0xc0 }, { 0x81,0x81,0x98,0x19 }, - { 0x4f,0x4f,0xd1,0x9e }, { 0xdc,0xdc,0x7f,0xa3 }, - { 0x22,0x22,0x66,0x44 }, { 0x2a,0x2a,0x7e,0x54 }, - { 0x90,0x90,0xab,0x3b }, { 0x88,0x88,0x83,0x0b }, - { 0x46,0x46,0xca,0x8c }, { 0xee,0xee,0x29,0xc7 }, - { 0xb8,0xb8,0xd3,0x6b }, { 0x14,0x14,0x3c,0x28 }, - { 0xde,0xde,0x79,0xa7 }, { 0x5e,0x5e,0xe2,0xbc }, - { 0x0b,0x0b,0x1d,0x16 }, { 0xdb,0xdb,0x76,0xad }, - { 0xe0,0xe0,0x3b,0xdb }, { 0x32,0x32,0x56,0x64 }, - { 0x3a,0x3a,0x4e,0x74 }, { 0x0a,0x0a,0x1e,0x14 }, - { 0x49,0x49,0xdb,0x92 }, { 0x06,0x06,0x0a,0x0c }, - { 0x24,0x24,0x6c,0x48 }, { 0x5c,0x5c,0xe4,0xb8 }, - { 0xc2,0xc2,0x5d,0x9f }, { 0xd3,0xd3,0x6e,0xbd }, - { 0xac,0xac,0xef,0x43 }, { 0x62,0x62,0xa6,0xc4 }, - { 0x91,0x91,0xa8,0x39 }, { 0x95,0x95,0xa4,0x31 }, - { 0xe4,0xe4,0x37,0xd3 }, { 0x79,0x79,0x8b,0xf2 }, - { 0xe7,0xe7,0x32,0xd5 }, { 0xc8,0xc8,0x43,0x8b }, - { 0x37,0x37,0x59,0x6e }, { 0x6d,0x6d,0xb7,0xda }, - { 0x8d,0x8d,0x8c,0x01 }, { 0xd5,0xd5,0x64,0xb1 }, - { 0x4e,0x4e,0xd2,0x9c }, { 0xa9,0xa9,0xe0,0x49 }, - { 0x6c,0x6c,0xb4,0xd8 }, { 0x56,0x56,0xfa,0xac }, - { 0xf4,0xf4,0x07,0xf3 }, { 0xea,0xea,0x25,0xcf }, - { 0x65,0x65,0xaf,0xca }, { 0x7a,0x7a,0x8e,0xf4 }, - { 0xae,0xae,0xe9,0x47 }, { 0x08,0x08,0x18,0x10 }, - { 0xba,0xba,0xd5,0x6f }, { 0x78,0x78,0x88,0xf0 }, - { 0x25,0x25,0x6f,0x4a }, { 0x2e,0x2e,0x72,0x5c }, - { 0x1c,0x1c,0x24,0x38 }, { 0xa6,0xa6,0xf1,0x57 }, - { 0xb4,0xb4,0xc7,0x73 }, { 0xc6,0xc6,0x51,0x97 }, - { 0xe8,0xe8,0x23,0xcb }, { 0xdd,0xdd,0x7c,0xa1 }, - { 0x74,0x74,0x9c,0xe8 }, { 0x1f,0x1f,0x21,0x3e }, - { 0x4b,0x4b,0xdd,0x96 }, { 0xbd,0xbd,0xdc,0x61 }, - { 0x8b,0x8b,0x86,0x0d }, { 0x8a,0x8a,0x85,0x0f }, - { 0x70,0x70,0x90,0xe0 }, { 0x3e,0x3e,0x42,0x7c }, - { 0xb5,0xb5,0xc4,0x71 }, { 0x66,0x66,0xaa,0xcc }, - { 0x48,0x48,0xd8,0x90 }, { 0x03,0x03,0x05,0x06 }, - { 0xf6,0xf6,0x01,0xf7 }, { 0x0e,0x0e,0x12,0x1c }, - { 0x61,0x61,0xa3,0xc2 }, { 0x35,0x35,0x5f,0x6a }, - { 0x57,0x57,0xf9,0xae }, { 0xb9,0xb9,0xd0,0x69 }, - { 0x86,0x86,0x91,0x17 }, { 0xc1,0xc1,0x58,0x99 }, - { 0x1d,0x1d,0x27,0x3a }, { 0x9e,0x9e,0xb9,0x27 }, - { 0xe1,0xe1,0x38,0xd9 }, { 0xf8,0xf8,0x13,0xeb }, - { 0x98,0x98,0xb3,0x2b }, { 0x11,0x11,0x33,0x22 }, - { 0x69,0x69,0xbb,0xd2 }, { 0xd9,0xd9,0x70,0xa9 }, - { 0x8e,0x8e,0x89,0x07 }, { 0x94,0x94,0xa7,0x33 }, - { 0x9b,0x9b,0xb6,0x2d }, { 0x1e,0x1e,0x22,0x3c }, - { 0x87,0x87,0x92,0x15 }, { 0xe9,0xe9,0x20,0xc9 }, - { 0xce,0xce,0x49,0x87 }, { 0x55,0x55,0xff,0xaa }, - { 0x28,0x28,0x78,0x50 }, { 0xdf,0xdf,0x7a,0xa5 }, - { 0x8c,0x8c,0x8f,0x03 }, { 0xa1,0xa1,0xf8,0x59 }, - { 0x89,0x89,0x80,0x09 }, { 0x0d,0x0d,0x17,0x1a }, - { 0xbf,0xbf,0xda,0x65 }, { 0xe6,0xe6,0x31,0xd7 }, - { 0x42,0x42,0xc6,0x84 }, { 0x68,0x68,0xb8,0xd0 }, - { 0x41,0x41,0xc3,0x82 }, { 0x99,0x99,0xb0,0x29 }, - { 0x2d,0x2d,0x77,0x5a }, { 0x0f,0x0f,0x11,0x1e }, - { 0xb0,0xb0,0xcb,0x7b }, { 0x54,0x54,0xfc,0xa8 }, - { 0xbb,0xbb,0xd6,0x6d }, { 0x16,0x16,0x3a,0x2c } - }; - -static const unsigned char T5[256][4] = - { - { 0x51,0xf4,0xa7,0x50 }, { 0x7e,0x41,0x65,0x53 }, - { 0x1a,0x17,0xa4,0xc3 }, { 0x3a,0x27,0x5e,0x96 }, - { 0x3b,0xab,0x6b,0xcb }, { 0x1f,0x9d,0x45,0xf1 }, - { 0xac,0xfa,0x58,0xab }, { 0x4b,0xe3,0x03,0x93 }, - { 0x20,0x30,0xfa,0x55 }, { 0xad,0x76,0x6d,0xf6 }, - { 0x88,0xcc,0x76,0x91 }, { 0xf5,0x02,0x4c,0x25 }, - { 0x4f,0xe5,0xd7,0xfc }, { 0xc5,0x2a,0xcb,0xd7 }, - { 0x26,0x35,0x44,0x80 }, { 0xb5,0x62,0xa3,0x8f }, - { 0xde,0xb1,0x5a,0x49 }, { 0x25,0xba,0x1b,0x67 }, - { 0x45,0xea,0x0e,0x98 }, { 0x5d,0xfe,0xc0,0xe1 }, - { 0xc3,0x2f,0x75,0x02 }, { 0x81,0x4c,0xf0,0x12 }, - { 0x8d,0x46,0x97,0xa3 }, { 0x6b,0xd3,0xf9,0xc6 }, - { 0x03,0x8f,0x5f,0xe7 }, { 0x15,0x92,0x9c,0x95 }, - { 0xbf,0x6d,0x7a,0xeb }, { 0x95,0x52,0x59,0xda }, - { 0xd4,0xbe,0x83,0x2d }, { 0x58,0x74,0x21,0xd3 }, - { 0x49,0xe0,0x69,0x29 }, { 0x8e,0xc9,0xc8,0x44 }, - { 0x75,0xc2,0x89,0x6a }, { 0xf4,0x8e,0x79,0x78 }, - { 0x99,0x58,0x3e,0x6b }, { 0x27,0xb9,0x71,0xdd }, - { 0xbe,0xe1,0x4f,0xb6 }, { 0xf0,0x88,0xad,0x17 }, - { 0xc9,0x20,0xac,0x66 }, { 0x7d,0xce,0x3a,0xb4 }, - { 0x63,0xdf,0x4a,0x18 }, { 0xe5,0x1a,0x31,0x82 }, - { 0x97,0x51,0x33,0x60 }, { 0x62,0x53,0x7f,0x45 }, - { 0xb1,0x64,0x77,0xe0 }, { 0xbb,0x6b,0xae,0x84 }, - { 0xfe,0x81,0xa0,0x1c }, { 0xf9,0x08,0x2b,0x94 }, - { 0x70,0x48,0x68,0x58 }, { 0x8f,0x45,0xfd,0x19 }, - { 0x94,0xde,0x6c,0x87 }, { 0x52,0x7b,0xf8,0xb7 }, - { 0xab,0x73,0xd3,0x23 }, { 0x72,0x4b,0x02,0xe2 }, - { 0xe3,0x1f,0x8f,0x57 }, { 0x66,0x55,0xab,0x2a }, - { 0xb2,0xeb,0x28,0x07 }, { 0x2f,0xb5,0xc2,0x03 }, - { 0x86,0xc5,0x7b,0x9a }, { 0xd3,0x37,0x08,0xa5 }, - { 0x30,0x28,0x87,0xf2 }, { 0x23,0xbf,0xa5,0xb2 }, - { 0x02,0x03,0x6a,0xba }, { 0xed,0x16,0x82,0x5c }, - { 0x8a,0xcf,0x1c,0x2b }, { 0xa7,0x79,0xb4,0x92 }, - { 0xf3,0x07,0xf2,0xf0 }, { 0x4e,0x69,0xe2,0xa1 }, - { 0x65,0xda,0xf4,0xcd }, { 0x06,0x05,0xbe,0xd5 }, - { 0xd1,0x34,0x62,0x1f }, { 0xc4,0xa6,0xfe,0x8a }, - { 0x34,0x2e,0x53,0x9d }, { 0xa2,0xf3,0x55,0xa0 }, - { 0x05,0x8a,0xe1,0x32 }, { 0xa4,0xf6,0xeb,0x75 }, - { 0x0b,0x83,0xec,0x39 }, { 0x40,0x60,0xef,0xaa }, - { 0x5e,0x71,0x9f,0x06 }, { 0xbd,0x6e,0x10,0x51 }, - { 0x3e,0x21,0x8a,0xf9 }, { 0x96,0xdd,0x06,0x3d }, - { 0xdd,0x3e,0x05,0xae }, { 0x4d,0xe6,0xbd,0x46 }, - { 0x91,0x54,0x8d,0xb5 }, { 0x71,0xc4,0x5d,0x05 }, - { 0x04,0x06,0xd4,0x6f }, { 0x60,0x50,0x15,0xff }, - { 0x19,0x98,0xfb,0x24 }, { 0xd6,0xbd,0xe9,0x97 }, - { 0x89,0x40,0x43,0xcc }, { 0x67,0xd9,0x9e,0x77 }, - { 0xb0,0xe8,0x42,0xbd }, { 0x07,0x89,0x8b,0x88 }, - { 0xe7,0x19,0x5b,0x38 }, { 0x79,0xc8,0xee,0xdb }, - { 0xa1,0x7c,0x0a,0x47 }, { 0x7c,0x42,0x0f,0xe9 }, - { 0xf8,0x84,0x1e,0xc9 }, { 0x00,0x00,0x00,0x00 }, - { 0x09,0x80,0x86,0x83 }, { 0x32,0x2b,0xed,0x48 }, - { 0x1e,0x11,0x70,0xac }, { 0x6c,0x5a,0x72,0x4e }, - { 0xfd,0x0e,0xff,0xfb }, { 0x0f,0x85,0x38,0x56 }, - { 0x3d,0xae,0xd5,0x1e }, { 0x36,0x2d,0x39,0x27 }, - { 0x0a,0x0f,0xd9,0x64 }, { 0x68,0x5c,0xa6,0x21 }, - { 0x9b,0x5b,0x54,0xd1 }, { 0x24,0x36,0x2e,0x3a }, - { 0x0c,0x0a,0x67,0xb1 }, { 0x93,0x57,0xe7,0x0f }, - { 0xb4,0xee,0x96,0xd2 }, { 0x1b,0x9b,0x91,0x9e }, - { 0x80,0xc0,0xc5,0x4f }, { 0x61,0xdc,0x20,0xa2 }, - { 0x5a,0x77,0x4b,0x69 }, { 0x1c,0x12,0x1a,0x16 }, - { 0xe2,0x93,0xba,0x0a }, { 0xc0,0xa0,0x2a,0xe5 }, - { 0x3c,0x22,0xe0,0x43 }, { 0x12,0x1b,0x17,0x1d }, - { 0x0e,0x09,0x0d,0x0b }, { 0xf2,0x8b,0xc7,0xad }, - { 0x2d,0xb6,0xa8,0xb9 }, { 0x14,0x1e,0xa9,0xc8 }, - { 0x57,0xf1,0x19,0x85 }, { 0xaf,0x75,0x07,0x4c }, - { 0xee,0x99,0xdd,0xbb }, { 0xa3,0x7f,0x60,0xfd }, - { 0xf7,0x01,0x26,0x9f }, { 0x5c,0x72,0xf5,0xbc }, - { 0x44,0x66,0x3b,0xc5 }, { 0x5b,0xfb,0x7e,0x34 }, - { 0x8b,0x43,0x29,0x76 }, { 0xcb,0x23,0xc6,0xdc }, - { 0xb6,0xed,0xfc,0x68 }, { 0xb8,0xe4,0xf1,0x63 }, - { 0xd7,0x31,0xdc,0xca }, { 0x42,0x63,0x85,0x10 }, - { 0x13,0x97,0x22,0x40 }, { 0x84,0xc6,0x11,0x20 }, - { 0x85,0x4a,0x24,0x7d }, { 0xd2,0xbb,0x3d,0xf8 }, - { 0xae,0xf9,0x32,0x11 }, { 0xc7,0x29,0xa1,0x6d }, - { 0x1d,0x9e,0x2f,0x4b }, { 0xdc,0xb2,0x30,0xf3 }, - { 0x0d,0x86,0x52,0xec }, { 0x77,0xc1,0xe3,0xd0 }, - { 0x2b,0xb3,0x16,0x6c }, { 0xa9,0x70,0xb9,0x99 }, - { 0x11,0x94,0x48,0xfa }, { 0x47,0xe9,0x64,0x22 }, - { 0xa8,0xfc,0x8c,0xc4 }, { 0xa0,0xf0,0x3f,0x1a }, - { 0x56,0x7d,0x2c,0xd8 }, { 0x22,0x33,0x90,0xef }, - { 0x87,0x49,0x4e,0xc7 }, { 0xd9,0x38,0xd1,0xc1 }, - { 0x8c,0xca,0xa2,0xfe }, { 0x98,0xd4,0x0b,0x36 }, - { 0xa6,0xf5,0x81,0xcf }, { 0xa5,0x7a,0xde,0x28 }, - { 0xda,0xb7,0x8e,0x26 }, { 0x3f,0xad,0xbf,0xa4 }, - { 0x2c,0x3a,0x9d,0xe4 }, { 0x50,0x78,0x92,0x0d }, - { 0x6a,0x5f,0xcc,0x9b }, { 0x54,0x7e,0x46,0x62 }, - { 0xf6,0x8d,0x13,0xc2 }, { 0x90,0xd8,0xb8,0xe8 }, - { 0x2e,0x39,0xf7,0x5e }, { 0x82,0xc3,0xaf,0xf5 }, - { 0x9f,0x5d,0x80,0xbe }, { 0x69,0xd0,0x93,0x7c }, - { 0x6f,0xd5,0x2d,0xa9 }, { 0xcf,0x25,0x12,0xb3 }, - { 0xc8,0xac,0x99,0x3b }, { 0x10,0x18,0x7d,0xa7 }, - { 0xe8,0x9c,0x63,0x6e }, { 0xdb,0x3b,0xbb,0x7b }, - { 0xcd,0x26,0x78,0x09 }, { 0x6e,0x59,0x18,0xf4 }, - { 0xec,0x9a,0xb7,0x01 }, { 0x83,0x4f,0x9a,0xa8 }, - { 0xe6,0x95,0x6e,0x65 }, { 0xaa,0xff,0xe6,0x7e }, - { 0x21,0xbc,0xcf,0x08 }, { 0xef,0x15,0xe8,0xe6 }, - { 0xba,0xe7,0x9b,0xd9 }, { 0x4a,0x6f,0x36,0xce }, - { 0xea,0x9f,0x09,0xd4 }, { 0x29,0xb0,0x7c,0xd6 }, - { 0x31,0xa4,0xb2,0xaf }, { 0x2a,0x3f,0x23,0x31 }, - { 0xc6,0xa5,0x94,0x30 }, { 0x35,0xa2,0x66,0xc0 }, - { 0x74,0x4e,0xbc,0x37 }, { 0xfc,0x82,0xca,0xa6 }, - { 0xe0,0x90,0xd0,0xb0 }, { 0x33,0xa7,0xd8,0x15 }, - { 0xf1,0x04,0x98,0x4a }, { 0x41,0xec,0xda,0xf7 }, - { 0x7f,0xcd,0x50,0x0e }, { 0x17,0x91,0xf6,0x2f }, - { 0x76,0x4d,0xd6,0x8d }, { 0x43,0xef,0xb0,0x4d }, - { 0xcc,0xaa,0x4d,0x54 }, { 0xe4,0x96,0x04,0xdf }, - { 0x9e,0xd1,0xb5,0xe3 }, { 0x4c,0x6a,0x88,0x1b }, - { 0xc1,0x2c,0x1f,0xb8 }, { 0x46,0x65,0x51,0x7f }, - { 0x9d,0x5e,0xea,0x04 }, { 0x01,0x8c,0x35,0x5d }, - { 0xfa,0x87,0x74,0x73 }, { 0xfb,0x0b,0x41,0x2e }, - { 0xb3,0x67,0x1d,0x5a }, { 0x92,0xdb,0xd2,0x52 }, - { 0xe9,0x10,0x56,0x33 }, { 0x6d,0xd6,0x47,0x13 }, - { 0x9a,0xd7,0x61,0x8c }, { 0x37,0xa1,0x0c,0x7a }, - { 0x59,0xf8,0x14,0x8e }, { 0xeb,0x13,0x3c,0x89 }, - { 0xce,0xa9,0x27,0xee }, { 0xb7,0x61,0xc9,0x35 }, - { 0xe1,0x1c,0xe5,0xed }, { 0x7a,0x47,0xb1,0x3c }, - { 0x9c,0xd2,0xdf,0x59 }, { 0x55,0xf2,0x73,0x3f }, - { 0x18,0x14,0xce,0x79 }, { 0x73,0xc7,0x37,0xbf }, - { 0x53,0xf7,0xcd,0xea }, { 0x5f,0xfd,0xaa,0x5b }, - { 0xdf,0x3d,0x6f,0x14 }, { 0x78,0x44,0xdb,0x86 }, - { 0xca,0xaf,0xf3,0x81 }, { 0xb9,0x68,0xc4,0x3e }, - { 0x38,0x24,0x34,0x2c }, { 0xc2,0xa3,0x40,0x5f }, - { 0x16,0x1d,0xc3,0x72 }, { 0xbc,0xe2,0x25,0x0c }, - { 0x28,0x3c,0x49,0x8b }, { 0xff,0x0d,0x95,0x41 }, - { 0x39,0xa8,0x01,0x71 }, { 0x08,0x0c,0xb3,0xde }, - { 0xd8,0xb4,0xe4,0x9c }, { 0x64,0x56,0xc1,0x90 }, - { 0x7b,0xcb,0x84,0x61 }, { 0xd5,0x32,0xb6,0x70 }, - { 0x48,0x6c,0x5c,0x74 }, { 0xd0,0xb8,0x57,0x42 } - }; - -static const unsigned char T6[256][4] = - { - { 0x50,0x51,0xf4,0xa7 }, { 0x53,0x7e,0x41,0x65 }, - { 0xc3,0x1a,0x17,0xa4 }, { 0x96,0x3a,0x27,0x5e }, - { 0xcb,0x3b,0xab,0x6b }, { 0xf1,0x1f,0x9d,0x45 }, - { 0xab,0xac,0xfa,0x58 }, { 0x93,0x4b,0xe3,0x03 }, - { 0x55,0x20,0x30,0xfa }, { 0xf6,0xad,0x76,0x6d }, - { 0x91,0x88,0xcc,0x76 }, { 0x25,0xf5,0x02,0x4c }, - { 0xfc,0x4f,0xe5,0xd7 }, { 0xd7,0xc5,0x2a,0xcb }, - { 0x80,0x26,0x35,0x44 }, { 0x8f,0xb5,0x62,0xa3 }, - { 0x49,0xde,0xb1,0x5a }, { 0x67,0x25,0xba,0x1b }, - { 0x98,0x45,0xea,0x0e }, { 0xe1,0x5d,0xfe,0xc0 }, - { 0x02,0xc3,0x2f,0x75 }, { 0x12,0x81,0x4c,0xf0 }, - { 0xa3,0x8d,0x46,0x97 }, { 0xc6,0x6b,0xd3,0xf9 }, - { 0xe7,0x03,0x8f,0x5f }, { 0x95,0x15,0x92,0x9c }, - { 0xeb,0xbf,0x6d,0x7a }, { 0xda,0x95,0x52,0x59 }, - { 0x2d,0xd4,0xbe,0x83 }, { 0xd3,0x58,0x74,0x21 }, - { 0x29,0x49,0xe0,0x69 }, { 0x44,0x8e,0xc9,0xc8 }, - { 0x6a,0x75,0xc2,0x89 }, { 0x78,0xf4,0x8e,0x79 }, - { 0x6b,0x99,0x58,0x3e }, { 0xdd,0x27,0xb9,0x71 }, - { 0xb6,0xbe,0xe1,0x4f }, { 0x17,0xf0,0x88,0xad }, - { 0x66,0xc9,0x20,0xac }, { 0xb4,0x7d,0xce,0x3a }, - { 0x18,0x63,0xdf,0x4a }, { 0x82,0xe5,0x1a,0x31 }, - { 0x60,0x97,0x51,0x33 }, { 0x45,0x62,0x53,0x7f }, - { 0xe0,0xb1,0x64,0x77 }, { 0x84,0xbb,0x6b,0xae }, - { 0x1c,0xfe,0x81,0xa0 }, { 0x94,0xf9,0x08,0x2b }, - { 0x58,0x70,0x48,0x68 }, { 0x19,0x8f,0x45,0xfd }, - { 0x87,0x94,0xde,0x6c }, { 0xb7,0x52,0x7b,0xf8 }, - { 0x23,0xab,0x73,0xd3 }, { 0xe2,0x72,0x4b,0x02 }, - { 0x57,0xe3,0x1f,0x8f }, { 0x2a,0x66,0x55,0xab }, - { 0x07,0xb2,0xeb,0x28 }, { 0x03,0x2f,0xb5,0xc2 }, - { 0x9a,0x86,0xc5,0x7b }, { 0xa5,0xd3,0x37,0x08 }, - { 0xf2,0x30,0x28,0x87 }, { 0xb2,0x23,0xbf,0xa5 }, - { 0xba,0x02,0x03,0x6a }, { 0x5c,0xed,0x16,0x82 }, - { 0x2b,0x8a,0xcf,0x1c }, { 0x92,0xa7,0x79,0xb4 }, - { 0xf0,0xf3,0x07,0xf2 }, { 0xa1,0x4e,0x69,0xe2 }, - { 0xcd,0x65,0xda,0xf4 }, { 0xd5,0x06,0x05,0xbe }, - { 0x1f,0xd1,0x34,0x62 }, { 0x8a,0xc4,0xa6,0xfe }, - { 0x9d,0x34,0x2e,0x53 }, { 0xa0,0xa2,0xf3,0x55 }, - { 0x32,0x05,0x8a,0xe1 }, { 0x75,0xa4,0xf6,0xeb }, - { 0x39,0x0b,0x83,0xec }, { 0xaa,0x40,0x60,0xef }, - { 0x06,0x5e,0x71,0x9f }, { 0x51,0xbd,0x6e,0x10 }, - { 0xf9,0x3e,0x21,0x8a }, { 0x3d,0x96,0xdd,0x06 }, - { 0xae,0xdd,0x3e,0x05 }, { 0x46,0x4d,0xe6,0xbd }, - { 0xb5,0x91,0x54,0x8d }, { 0x05,0x71,0xc4,0x5d }, - { 0x6f,0x04,0x06,0xd4 }, { 0xff,0x60,0x50,0x15 }, - { 0x24,0x19,0x98,0xfb }, { 0x97,0xd6,0xbd,0xe9 }, - { 0xcc,0x89,0x40,0x43 }, { 0x77,0x67,0xd9,0x9e }, - { 0xbd,0xb0,0xe8,0x42 }, { 0x88,0x07,0x89,0x8b }, - { 0x38,0xe7,0x19,0x5b }, { 0xdb,0x79,0xc8,0xee }, - { 0x47,0xa1,0x7c,0x0a }, { 0xe9,0x7c,0x42,0x0f }, - { 0xc9,0xf8,0x84,0x1e }, { 0x00,0x00,0x00,0x00 }, - { 0x83,0x09,0x80,0x86 }, { 0x48,0x32,0x2b,0xed }, - { 0xac,0x1e,0x11,0x70 }, { 0x4e,0x6c,0x5a,0x72 }, - { 0xfb,0xfd,0x0e,0xff }, { 0x56,0x0f,0x85,0x38 }, - { 0x1e,0x3d,0xae,0xd5 }, { 0x27,0x36,0x2d,0x39 }, - { 0x64,0x0a,0x0f,0xd9 }, { 0x21,0x68,0x5c,0xa6 }, - { 0xd1,0x9b,0x5b,0x54 }, { 0x3a,0x24,0x36,0x2e }, - { 0xb1,0x0c,0x0a,0x67 }, { 0x0f,0x93,0x57,0xe7 }, - { 0xd2,0xb4,0xee,0x96 }, { 0x9e,0x1b,0x9b,0x91 }, - { 0x4f,0x80,0xc0,0xc5 }, { 0xa2,0x61,0xdc,0x20 }, - { 0x69,0x5a,0x77,0x4b }, { 0x16,0x1c,0x12,0x1a }, - { 0x0a,0xe2,0x93,0xba }, { 0xe5,0xc0,0xa0,0x2a }, - { 0x43,0x3c,0x22,0xe0 }, { 0x1d,0x12,0x1b,0x17 }, - { 0x0b,0x0e,0x09,0x0d }, { 0xad,0xf2,0x8b,0xc7 }, - { 0xb9,0x2d,0xb6,0xa8 }, { 0xc8,0x14,0x1e,0xa9 }, - { 0x85,0x57,0xf1,0x19 }, { 0x4c,0xaf,0x75,0x07 }, - { 0xbb,0xee,0x99,0xdd }, { 0xfd,0xa3,0x7f,0x60 }, - { 0x9f,0xf7,0x01,0x26 }, { 0xbc,0x5c,0x72,0xf5 }, - { 0xc5,0x44,0x66,0x3b }, { 0x34,0x5b,0xfb,0x7e }, - { 0x76,0x8b,0x43,0x29 }, { 0xdc,0xcb,0x23,0xc6 }, - { 0x68,0xb6,0xed,0xfc }, { 0x63,0xb8,0xe4,0xf1 }, - { 0xca,0xd7,0x31,0xdc }, { 0x10,0x42,0x63,0x85 }, - { 0x40,0x13,0x97,0x22 }, { 0x20,0x84,0xc6,0x11 }, - { 0x7d,0x85,0x4a,0x24 }, { 0xf8,0xd2,0xbb,0x3d }, - { 0x11,0xae,0xf9,0x32 }, { 0x6d,0xc7,0x29,0xa1 }, - { 0x4b,0x1d,0x9e,0x2f }, { 0xf3,0xdc,0xb2,0x30 }, - { 0xec,0x0d,0x86,0x52 }, { 0xd0,0x77,0xc1,0xe3 }, - { 0x6c,0x2b,0xb3,0x16 }, { 0x99,0xa9,0x70,0xb9 }, - { 0xfa,0x11,0x94,0x48 }, { 0x22,0x47,0xe9,0x64 }, - { 0xc4,0xa8,0xfc,0x8c }, { 0x1a,0xa0,0xf0,0x3f }, - { 0xd8,0x56,0x7d,0x2c }, { 0xef,0x22,0x33,0x90 }, - { 0xc7,0x87,0x49,0x4e }, { 0xc1,0xd9,0x38,0xd1 }, - { 0xfe,0x8c,0xca,0xa2 }, { 0x36,0x98,0xd4,0x0b }, - { 0xcf,0xa6,0xf5,0x81 }, { 0x28,0xa5,0x7a,0xde }, - { 0x26,0xda,0xb7,0x8e }, { 0xa4,0x3f,0xad,0xbf }, - { 0xe4,0x2c,0x3a,0x9d }, { 0x0d,0x50,0x78,0x92 }, - { 0x9b,0x6a,0x5f,0xcc }, { 0x62,0x54,0x7e,0x46 }, - { 0xc2,0xf6,0x8d,0x13 }, { 0xe8,0x90,0xd8,0xb8 }, - { 0x5e,0x2e,0x39,0xf7 }, { 0xf5,0x82,0xc3,0xaf }, - { 0xbe,0x9f,0x5d,0x80 }, { 0x7c,0x69,0xd0,0x93 }, - { 0xa9,0x6f,0xd5,0x2d }, { 0xb3,0xcf,0x25,0x12 }, - { 0x3b,0xc8,0xac,0x99 }, { 0xa7,0x10,0x18,0x7d }, - { 0x6e,0xe8,0x9c,0x63 }, { 0x7b,0xdb,0x3b,0xbb }, - { 0x09,0xcd,0x26,0x78 }, { 0xf4,0x6e,0x59,0x18 }, - { 0x01,0xec,0x9a,0xb7 }, { 0xa8,0x83,0x4f,0x9a }, - { 0x65,0xe6,0x95,0x6e }, { 0x7e,0xaa,0xff,0xe6 }, - { 0x08,0x21,0xbc,0xcf }, { 0xe6,0xef,0x15,0xe8 }, - { 0xd9,0xba,0xe7,0x9b }, { 0xce,0x4a,0x6f,0x36 }, - { 0xd4,0xea,0x9f,0x09 }, { 0xd6,0x29,0xb0,0x7c }, - { 0xaf,0x31,0xa4,0xb2 }, { 0x31,0x2a,0x3f,0x23 }, - { 0x30,0xc6,0xa5,0x94 }, { 0xc0,0x35,0xa2,0x66 }, - { 0x37,0x74,0x4e,0xbc }, { 0xa6,0xfc,0x82,0xca }, - { 0xb0,0xe0,0x90,0xd0 }, { 0x15,0x33,0xa7,0xd8 }, - { 0x4a,0xf1,0x04,0x98 }, { 0xf7,0x41,0xec,0xda }, - { 0x0e,0x7f,0xcd,0x50 }, { 0x2f,0x17,0x91,0xf6 }, - { 0x8d,0x76,0x4d,0xd6 }, { 0x4d,0x43,0xef,0xb0 }, - { 0x54,0xcc,0xaa,0x4d }, { 0xdf,0xe4,0x96,0x04 }, - { 0xe3,0x9e,0xd1,0xb5 }, { 0x1b,0x4c,0x6a,0x88 }, - { 0xb8,0xc1,0x2c,0x1f }, { 0x7f,0x46,0x65,0x51 }, - { 0x04,0x9d,0x5e,0xea }, { 0x5d,0x01,0x8c,0x35 }, - { 0x73,0xfa,0x87,0x74 }, { 0x2e,0xfb,0x0b,0x41 }, - { 0x5a,0xb3,0x67,0x1d }, { 0x52,0x92,0xdb,0xd2 }, - { 0x33,0xe9,0x10,0x56 }, { 0x13,0x6d,0xd6,0x47 }, - { 0x8c,0x9a,0xd7,0x61 }, { 0x7a,0x37,0xa1,0x0c }, - { 0x8e,0x59,0xf8,0x14 }, { 0x89,0xeb,0x13,0x3c }, - { 0xee,0xce,0xa9,0x27 }, { 0x35,0xb7,0x61,0xc9 }, - { 0xed,0xe1,0x1c,0xe5 }, { 0x3c,0x7a,0x47,0xb1 }, - { 0x59,0x9c,0xd2,0xdf }, { 0x3f,0x55,0xf2,0x73 }, - { 0x79,0x18,0x14,0xce }, { 0xbf,0x73,0xc7,0x37 }, - { 0xea,0x53,0xf7,0xcd }, { 0x5b,0x5f,0xfd,0xaa }, - { 0x14,0xdf,0x3d,0x6f }, { 0x86,0x78,0x44,0xdb }, - { 0x81,0xca,0xaf,0xf3 }, { 0x3e,0xb9,0x68,0xc4 }, - { 0x2c,0x38,0x24,0x34 }, { 0x5f,0xc2,0xa3,0x40 }, - { 0x72,0x16,0x1d,0xc3 }, { 0x0c,0xbc,0xe2,0x25 }, - { 0x8b,0x28,0x3c,0x49 }, { 0x41,0xff,0x0d,0x95 }, - { 0x71,0x39,0xa8,0x01 }, { 0xde,0x08,0x0c,0xb3 }, - { 0x9c,0xd8,0xb4,0xe4 }, { 0x90,0x64,0x56,0xc1 }, - { 0x61,0x7b,0xcb,0x84 }, { 0x70,0xd5,0x32,0xb6 }, - { 0x74,0x48,0x6c,0x5c }, { 0x42,0xd0,0xb8,0x57 } - }; - -static const unsigned char T7[256][4] = - { - { 0xa7,0x50,0x51,0xf4 }, { 0x65,0x53,0x7e,0x41 }, - { 0xa4,0xc3,0x1a,0x17 }, { 0x5e,0x96,0x3a,0x27 }, - { 0x6b,0xcb,0x3b,0xab }, { 0x45,0xf1,0x1f,0x9d }, - { 0x58,0xab,0xac,0xfa }, { 0x03,0x93,0x4b,0xe3 }, - { 0xfa,0x55,0x20,0x30 }, { 0x6d,0xf6,0xad,0x76 }, - { 0x76,0x91,0x88,0xcc }, { 0x4c,0x25,0xf5,0x02 }, - { 0xd7,0xfc,0x4f,0xe5 }, { 0xcb,0xd7,0xc5,0x2a }, - { 0x44,0x80,0x26,0x35 }, { 0xa3,0x8f,0xb5,0x62 }, - { 0x5a,0x49,0xde,0xb1 }, { 0x1b,0x67,0x25,0xba }, - { 0x0e,0x98,0x45,0xea }, { 0xc0,0xe1,0x5d,0xfe }, - { 0x75,0x02,0xc3,0x2f }, { 0xf0,0x12,0x81,0x4c }, - { 0x97,0xa3,0x8d,0x46 }, { 0xf9,0xc6,0x6b,0xd3 }, - { 0x5f,0xe7,0x03,0x8f }, { 0x9c,0x95,0x15,0x92 }, - { 0x7a,0xeb,0xbf,0x6d }, { 0x59,0xda,0x95,0x52 }, - { 0x83,0x2d,0xd4,0xbe }, { 0x21,0xd3,0x58,0x74 }, - { 0x69,0x29,0x49,0xe0 }, { 0xc8,0x44,0x8e,0xc9 }, - { 0x89,0x6a,0x75,0xc2 }, { 0x79,0x78,0xf4,0x8e }, - { 0x3e,0x6b,0x99,0x58 }, { 0x71,0xdd,0x27,0xb9 }, - { 0x4f,0xb6,0xbe,0xe1 }, { 0xad,0x17,0xf0,0x88 }, - { 0xac,0x66,0xc9,0x20 }, { 0x3a,0xb4,0x7d,0xce }, - { 0x4a,0x18,0x63,0xdf }, { 0x31,0x82,0xe5,0x1a }, - { 0x33,0x60,0x97,0x51 }, { 0x7f,0x45,0x62,0x53 }, - { 0x77,0xe0,0xb1,0x64 }, { 0xae,0x84,0xbb,0x6b }, - { 0xa0,0x1c,0xfe,0x81 }, { 0x2b,0x94,0xf9,0x08 }, - { 0x68,0x58,0x70,0x48 }, { 0xfd,0x19,0x8f,0x45 }, - { 0x6c,0x87,0x94,0xde }, { 0xf8,0xb7,0x52,0x7b }, - { 0xd3,0x23,0xab,0x73 }, { 0x02,0xe2,0x72,0x4b }, - { 0x8f,0x57,0xe3,0x1f }, { 0xab,0x2a,0x66,0x55 }, - { 0x28,0x07,0xb2,0xeb }, { 0xc2,0x03,0x2f,0xb5 }, - { 0x7b,0x9a,0x86,0xc5 }, { 0x08,0xa5,0xd3,0x37 }, - { 0x87,0xf2,0x30,0x28 }, { 0xa5,0xb2,0x23,0xbf }, - { 0x6a,0xba,0x02,0x03 }, { 0x82,0x5c,0xed,0x16 }, - { 0x1c,0x2b,0x8a,0xcf }, { 0xb4,0x92,0xa7,0x79 }, - { 0xf2,0xf0,0xf3,0x07 }, { 0xe2,0xa1,0x4e,0x69 }, - { 0xf4,0xcd,0x65,0xda }, { 0xbe,0xd5,0x06,0x05 }, - { 0x62,0x1f,0xd1,0x34 }, { 0xfe,0x8a,0xc4,0xa6 }, - { 0x53,0x9d,0x34,0x2e }, { 0x55,0xa0,0xa2,0xf3 }, - { 0xe1,0x32,0x05,0x8a }, { 0xeb,0x75,0xa4,0xf6 }, - { 0xec,0x39,0x0b,0x83 }, { 0xef,0xaa,0x40,0x60 }, - { 0x9f,0x06,0x5e,0x71 }, { 0x10,0x51,0xbd,0x6e }, - { 0x8a,0xf9,0x3e,0x21 }, { 0x06,0x3d,0x96,0xdd }, - { 0x05,0xae,0xdd,0x3e }, { 0xbd,0x46,0x4d,0xe6 }, - { 0x8d,0xb5,0x91,0x54 }, { 0x5d,0x05,0x71,0xc4 }, - { 0xd4,0x6f,0x04,0x06 }, { 0x15,0xff,0x60,0x50 }, - { 0xfb,0x24,0x19,0x98 }, { 0xe9,0x97,0xd6,0xbd }, - { 0x43,0xcc,0x89,0x40 }, { 0x9e,0x77,0x67,0xd9 }, - { 0x42,0xbd,0xb0,0xe8 }, { 0x8b,0x88,0x07,0x89 }, - { 0x5b,0x38,0xe7,0x19 }, { 0xee,0xdb,0x79,0xc8 }, - { 0x0a,0x47,0xa1,0x7c }, { 0x0f,0xe9,0x7c,0x42 }, - { 0x1e,0xc9,0xf8,0x84 }, { 0x00,0x00,0x00,0x00 }, - { 0x86,0x83,0x09,0x80 }, { 0xed,0x48,0x32,0x2b }, - { 0x70,0xac,0x1e,0x11 }, { 0x72,0x4e,0x6c,0x5a }, - { 0xff,0xfb,0xfd,0x0e }, { 0x38,0x56,0x0f,0x85 }, - { 0xd5,0x1e,0x3d,0xae }, { 0x39,0x27,0x36,0x2d }, - { 0xd9,0x64,0x0a,0x0f }, { 0xa6,0x21,0x68,0x5c }, - { 0x54,0xd1,0x9b,0x5b }, { 0x2e,0x3a,0x24,0x36 }, - { 0x67,0xb1,0x0c,0x0a }, { 0xe7,0x0f,0x93,0x57 }, - { 0x96,0xd2,0xb4,0xee }, { 0x91,0x9e,0x1b,0x9b }, - { 0xc5,0x4f,0x80,0xc0 }, { 0x20,0xa2,0x61,0xdc }, - { 0x4b,0x69,0x5a,0x77 }, { 0x1a,0x16,0x1c,0x12 }, - { 0xba,0x0a,0xe2,0x93 }, { 0x2a,0xe5,0xc0,0xa0 }, - { 0xe0,0x43,0x3c,0x22 }, { 0x17,0x1d,0x12,0x1b }, - { 0x0d,0x0b,0x0e,0x09 }, { 0xc7,0xad,0xf2,0x8b }, - { 0xa8,0xb9,0x2d,0xb6 }, { 0xa9,0xc8,0x14,0x1e }, - { 0x19,0x85,0x57,0xf1 }, { 0x07,0x4c,0xaf,0x75 }, - { 0xdd,0xbb,0xee,0x99 }, { 0x60,0xfd,0xa3,0x7f }, - { 0x26,0x9f,0xf7,0x01 }, { 0xf5,0xbc,0x5c,0x72 }, - { 0x3b,0xc5,0x44,0x66 }, { 0x7e,0x34,0x5b,0xfb }, - { 0x29,0x76,0x8b,0x43 }, { 0xc6,0xdc,0xcb,0x23 }, - { 0xfc,0x68,0xb6,0xed }, { 0xf1,0x63,0xb8,0xe4 }, - { 0xdc,0xca,0xd7,0x31 }, { 0x85,0x10,0x42,0x63 }, - { 0x22,0x40,0x13,0x97 }, { 0x11,0x20,0x84,0xc6 }, - { 0x24,0x7d,0x85,0x4a }, { 0x3d,0xf8,0xd2,0xbb }, - { 0x32,0x11,0xae,0xf9 }, { 0xa1,0x6d,0xc7,0x29 }, - { 0x2f,0x4b,0x1d,0x9e }, { 0x30,0xf3,0xdc,0xb2 }, - { 0x52,0xec,0x0d,0x86 }, { 0xe3,0xd0,0x77,0xc1 }, - { 0x16,0x6c,0x2b,0xb3 }, { 0xb9,0x99,0xa9,0x70 }, - { 0x48,0xfa,0x11,0x94 }, { 0x64,0x22,0x47,0xe9 }, - { 0x8c,0xc4,0xa8,0xfc }, { 0x3f,0x1a,0xa0,0xf0 }, - { 0x2c,0xd8,0x56,0x7d }, { 0x90,0xef,0x22,0x33 }, - { 0x4e,0xc7,0x87,0x49 }, { 0xd1,0xc1,0xd9,0x38 }, - { 0xa2,0xfe,0x8c,0xca }, { 0x0b,0x36,0x98,0xd4 }, - { 0x81,0xcf,0xa6,0xf5 }, { 0xde,0x28,0xa5,0x7a }, - { 0x8e,0x26,0xda,0xb7 }, { 0xbf,0xa4,0x3f,0xad }, - { 0x9d,0xe4,0x2c,0x3a }, { 0x92,0x0d,0x50,0x78 }, - { 0xcc,0x9b,0x6a,0x5f }, { 0x46,0x62,0x54,0x7e }, - { 0x13,0xc2,0xf6,0x8d }, { 0xb8,0xe8,0x90,0xd8 }, - { 0xf7,0x5e,0x2e,0x39 }, { 0xaf,0xf5,0x82,0xc3 }, - { 0x80,0xbe,0x9f,0x5d }, { 0x93,0x7c,0x69,0xd0 }, - { 0x2d,0xa9,0x6f,0xd5 }, { 0x12,0xb3,0xcf,0x25 }, - { 0x99,0x3b,0xc8,0xac }, { 0x7d,0xa7,0x10,0x18 }, - { 0x63,0x6e,0xe8,0x9c }, { 0xbb,0x7b,0xdb,0x3b }, - { 0x78,0x09,0xcd,0x26 }, { 0x18,0xf4,0x6e,0x59 }, - { 0xb7,0x01,0xec,0x9a }, { 0x9a,0xa8,0x83,0x4f }, - { 0x6e,0x65,0xe6,0x95 }, { 0xe6,0x7e,0xaa,0xff }, - { 0xcf,0x08,0x21,0xbc }, { 0xe8,0xe6,0xef,0x15 }, - { 0x9b,0xd9,0xba,0xe7 }, { 0x36,0xce,0x4a,0x6f }, - { 0x09,0xd4,0xea,0x9f }, { 0x7c,0xd6,0x29,0xb0 }, - { 0xb2,0xaf,0x31,0xa4 }, { 0x23,0x31,0x2a,0x3f }, - { 0x94,0x30,0xc6,0xa5 }, { 0x66,0xc0,0x35,0xa2 }, - { 0xbc,0x37,0x74,0x4e }, { 0xca,0xa6,0xfc,0x82 }, - { 0xd0,0xb0,0xe0,0x90 }, { 0xd8,0x15,0x33,0xa7 }, - { 0x98,0x4a,0xf1,0x04 }, { 0xda,0xf7,0x41,0xec }, - { 0x50,0x0e,0x7f,0xcd }, { 0xf6,0x2f,0x17,0x91 }, - { 0xd6,0x8d,0x76,0x4d }, { 0xb0,0x4d,0x43,0xef }, - { 0x4d,0x54,0xcc,0xaa }, { 0x04,0xdf,0xe4,0x96 }, - { 0xb5,0xe3,0x9e,0xd1 }, { 0x88,0x1b,0x4c,0x6a }, - { 0x1f,0xb8,0xc1,0x2c }, { 0x51,0x7f,0x46,0x65 }, - { 0xea,0x04,0x9d,0x5e }, { 0x35,0x5d,0x01,0x8c }, - { 0x74,0x73,0xfa,0x87 }, { 0x41,0x2e,0xfb,0x0b }, - { 0x1d,0x5a,0xb3,0x67 }, { 0xd2,0x52,0x92,0xdb }, - { 0x56,0x33,0xe9,0x10 }, { 0x47,0x13,0x6d,0xd6 }, - { 0x61,0x8c,0x9a,0xd7 }, { 0x0c,0x7a,0x37,0xa1 }, - { 0x14,0x8e,0x59,0xf8 }, { 0x3c,0x89,0xeb,0x13 }, - { 0x27,0xee,0xce,0xa9 }, { 0xc9,0x35,0xb7,0x61 }, - { 0xe5,0xed,0xe1,0x1c }, { 0xb1,0x3c,0x7a,0x47 }, - { 0xdf,0x59,0x9c,0xd2 }, { 0x73,0x3f,0x55,0xf2 }, - { 0xce,0x79,0x18,0x14 }, { 0x37,0xbf,0x73,0xc7 }, - { 0xcd,0xea,0x53,0xf7 }, { 0xaa,0x5b,0x5f,0xfd }, - { 0x6f,0x14,0xdf,0x3d }, { 0xdb,0x86,0x78,0x44 }, - { 0xf3,0x81,0xca,0xaf }, { 0xc4,0x3e,0xb9,0x68 }, - { 0x34,0x2c,0x38,0x24 }, { 0x40,0x5f,0xc2,0xa3 }, - { 0xc3,0x72,0x16,0x1d }, { 0x25,0x0c,0xbc,0xe2 }, - { 0x49,0x8b,0x28,0x3c }, { 0x95,0x41,0xff,0x0d }, - { 0x01,0x71,0x39,0xa8 }, { 0xb3,0xde,0x08,0x0c }, - { 0xe4,0x9c,0xd8,0xb4 }, { 0xc1,0x90,0x64,0x56 }, - { 0x84,0x61,0x7b,0xcb }, { 0xb6,0x70,0xd5,0x32 }, - { 0x5c,0x74,0x48,0x6c }, { 0x57,0x42,0xd0,0xb8 } - }; - -static const unsigned char T8[256][4] = - { - { 0xf4,0xa7,0x50,0x51 }, { 0x41,0x65,0x53,0x7e }, - { 0x17,0xa4,0xc3,0x1a }, { 0x27,0x5e,0x96,0x3a }, - { 0xab,0x6b,0xcb,0x3b }, { 0x9d,0x45,0xf1,0x1f }, - { 0xfa,0x58,0xab,0xac }, { 0xe3,0x03,0x93,0x4b }, - { 0x30,0xfa,0x55,0x20 }, { 0x76,0x6d,0xf6,0xad }, - { 0xcc,0x76,0x91,0x88 }, { 0x02,0x4c,0x25,0xf5 }, - { 0xe5,0xd7,0xfc,0x4f }, { 0x2a,0xcb,0xd7,0xc5 }, - { 0x35,0x44,0x80,0x26 }, { 0x62,0xa3,0x8f,0xb5 }, - { 0xb1,0x5a,0x49,0xde }, { 0xba,0x1b,0x67,0x25 }, - { 0xea,0x0e,0x98,0x45 }, { 0xfe,0xc0,0xe1,0x5d }, - { 0x2f,0x75,0x02,0xc3 }, { 0x4c,0xf0,0x12,0x81 }, - { 0x46,0x97,0xa3,0x8d }, { 0xd3,0xf9,0xc6,0x6b }, - { 0x8f,0x5f,0xe7,0x03 }, { 0x92,0x9c,0x95,0x15 }, - { 0x6d,0x7a,0xeb,0xbf }, { 0x52,0x59,0xda,0x95 }, - { 0xbe,0x83,0x2d,0xd4 }, { 0x74,0x21,0xd3,0x58 }, - { 0xe0,0x69,0x29,0x49 }, { 0xc9,0xc8,0x44,0x8e }, - { 0xc2,0x89,0x6a,0x75 }, { 0x8e,0x79,0x78,0xf4 }, - { 0x58,0x3e,0x6b,0x99 }, { 0xb9,0x71,0xdd,0x27 }, - { 0xe1,0x4f,0xb6,0xbe }, { 0x88,0xad,0x17,0xf0 }, - { 0x20,0xac,0x66,0xc9 }, { 0xce,0x3a,0xb4,0x7d }, - { 0xdf,0x4a,0x18,0x63 }, { 0x1a,0x31,0x82,0xe5 }, - { 0x51,0x33,0x60,0x97 }, { 0x53,0x7f,0x45,0x62 }, - { 0x64,0x77,0xe0,0xb1 }, { 0x6b,0xae,0x84,0xbb }, - { 0x81,0xa0,0x1c,0xfe }, { 0x08,0x2b,0x94,0xf9 }, - { 0x48,0x68,0x58,0x70 }, { 0x45,0xfd,0x19,0x8f }, - { 0xde,0x6c,0x87,0x94 }, { 0x7b,0xf8,0xb7,0x52 }, - { 0x73,0xd3,0x23,0xab }, { 0x4b,0x02,0xe2,0x72 }, - { 0x1f,0x8f,0x57,0xe3 }, { 0x55,0xab,0x2a,0x66 }, - { 0xeb,0x28,0x07,0xb2 }, { 0xb5,0xc2,0x03,0x2f }, - { 0xc5,0x7b,0x9a,0x86 }, { 0x37,0x08,0xa5,0xd3 }, - { 0x28,0x87,0xf2,0x30 }, { 0xbf,0xa5,0xb2,0x23 }, - { 0x03,0x6a,0xba,0x02 }, { 0x16,0x82,0x5c,0xed }, - { 0xcf,0x1c,0x2b,0x8a }, { 0x79,0xb4,0x92,0xa7 }, - { 0x07,0xf2,0xf0,0xf3 }, { 0x69,0xe2,0xa1,0x4e }, - { 0xda,0xf4,0xcd,0x65 }, { 0x05,0xbe,0xd5,0x06 }, - { 0x34,0x62,0x1f,0xd1 }, { 0xa6,0xfe,0x8a,0xc4 }, - { 0x2e,0x53,0x9d,0x34 }, { 0xf3,0x55,0xa0,0xa2 }, - { 0x8a,0xe1,0x32,0x05 }, { 0xf6,0xeb,0x75,0xa4 }, - { 0x83,0xec,0x39,0x0b }, { 0x60,0xef,0xaa,0x40 }, - { 0x71,0x9f,0x06,0x5e }, { 0x6e,0x10,0x51,0xbd }, - { 0x21,0x8a,0xf9,0x3e }, { 0xdd,0x06,0x3d,0x96 }, - { 0x3e,0x05,0xae,0xdd }, { 0xe6,0xbd,0x46,0x4d }, - { 0x54,0x8d,0xb5,0x91 }, { 0xc4,0x5d,0x05,0x71 }, - { 0x06,0xd4,0x6f,0x04 }, { 0x50,0x15,0xff,0x60 }, - { 0x98,0xfb,0x24,0x19 }, { 0xbd,0xe9,0x97,0xd6 }, - { 0x40,0x43,0xcc,0x89 }, { 0xd9,0x9e,0x77,0x67 }, - { 0xe8,0x42,0xbd,0xb0 }, { 0x89,0x8b,0x88,0x07 }, - { 0x19,0x5b,0x38,0xe7 }, { 0xc8,0xee,0xdb,0x79 }, - { 0x7c,0x0a,0x47,0xa1 }, { 0x42,0x0f,0xe9,0x7c }, - { 0x84,0x1e,0xc9,0xf8 }, { 0x00,0x00,0x00,0x00 }, - { 0x80,0x86,0x83,0x09 }, { 0x2b,0xed,0x48,0x32 }, - { 0x11,0x70,0xac,0x1e }, { 0x5a,0x72,0x4e,0x6c }, - { 0x0e,0xff,0xfb,0xfd }, { 0x85,0x38,0x56,0x0f }, - { 0xae,0xd5,0x1e,0x3d }, { 0x2d,0x39,0x27,0x36 }, - { 0x0f,0xd9,0x64,0x0a }, { 0x5c,0xa6,0x21,0x68 }, - { 0x5b,0x54,0xd1,0x9b }, { 0x36,0x2e,0x3a,0x24 }, - { 0x0a,0x67,0xb1,0x0c }, { 0x57,0xe7,0x0f,0x93 }, - { 0xee,0x96,0xd2,0xb4 }, { 0x9b,0x91,0x9e,0x1b }, - { 0xc0,0xc5,0x4f,0x80 }, { 0xdc,0x20,0xa2,0x61 }, - { 0x77,0x4b,0x69,0x5a }, { 0x12,0x1a,0x16,0x1c }, - { 0x93,0xba,0x0a,0xe2 }, { 0xa0,0x2a,0xe5,0xc0 }, - { 0x22,0xe0,0x43,0x3c }, { 0x1b,0x17,0x1d,0x12 }, - { 0x09,0x0d,0x0b,0x0e }, { 0x8b,0xc7,0xad,0xf2 }, - { 0xb6,0xa8,0xb9,0x2d }, { 0x1e,0xa9,0xc8,0x14 }, - { 0xf1,0x19,0x85,0x57 }, { 0x75,0x07,0x4c,0xaf }, - { 0x99,0xdd,0xbb,0xee }, { 0x7f,0x60,0xfd,0xa3 }, - { 0x01,0x26,0x9f,0xf7 }, { 0x72,0xf5,0xbc,0x5c }, - { 0x66,0x3b,0xc5,0x44 }, { 0xfb,0x7e,0x34,0x5b }, - { 0x43,0x29,0x76,0x8b }, { 0x23,0xc6,0xdc,0xcb }, - { 0xed,0xfc,0x68,0xb6 }, { 0xe4,0xf1,0x63,0xb8 }, - { 0x31,0xdc,0xca,0xd7 }, { 0x63,0x85,0x10,0x42 }, - { 0x97,0x22,0x40,0x13 }, { 0xc6,0x11,0x20,0x84 }, - { 0x4a,0x24,0x7d,0x85 }, { 0xbb,0x3d,0xf8,0xd2 }, - { 0xf9,0x32,0x11,0xae }, { 0x29,0xa1,0x6d,0xc7 }, - { 0x9e,0x2f,0x4b,0x1d }, { 0xb2,0x30,0xf3,0xdc }, - { 0x86,0x52,0xec,0x0d }, { 0xc1,0xe3,0xd0,0x77 }, - { 0xb3,0x16,0x6c,0x2b }, { 0x70,0xb9,0x99,0xa9 }, - { 0x94,0x48,0xfa,0x11 }, { 0xe9,0x64,0x22,0x47 }, - { 0xfc,0x8c,0xc4,0xa8 }, { 0xf0,0x3f,0x1a,0xa0 }, - { 0x7d,0x2c,0xd8,0x56 }, { 0x33,0x90,0xef,0x22 }, - { 0x49,0x4e,0xc7,0x87 }, { 0x38,0xd1,0xc1,0xd9 }, - { 0xca,0xa2,0xfe,0x8c }, { 0xd4,0x0b,0x36,0x98 }, - { 0xf5,0x81,0xcf,0xa6 }, { 0x7a,0xde,0x28,0xa5 }, - { 0xb7,0x8e,0x26,0xda }, { 0xad,0xbf,0xa4,0x3f }, - { 0x3a,0x9d,0xe4,0x2c }, { 0x78,0x92,0x0d,0x50 }, - { 0x5f,0xcc,0x9b,0x6a }, { 0x7e,0x46,0x62,0x54 }, - { 0x8d,0x13,0xc2,0xf6 }, { 0xd8,0xb8,0xe8,0x90 }, - { 0x39,0xf7,0x5e,0x2e }, { 0xc3,0xaf,0xf5,0x82 }, - { 0x5d,0x80,0xbe,0x9f }, { 0xd0,0x93,0x7c,0x69 }, - { 0xd5,0x2d,0xa9,0x6f }, { 0x25,0x12,0xb3,0xcf }, - { 0xac,0x99,0x3b,0xc8 }, { 0x18,0x7d,0xa7,0x10 }, - { 0x9c,0x63,0x6e,0xe8 }, { 0x3b,0xbb,0x7b,0xdb }, - { 0x26,0x78,0x09,0xcd }, { 0x59,0x18,0xf4,0x6e }, - { 0x9a,0xb7,0x01,0xec }, { 0x4f,0x9a,0xa8,0x83 }, - { 0x95,0x6e,0x65,0xe6 }, { 0xff,0xe6,0x7e,0xaa }, - { 0xbc,0xcf,0x08,0x21 }, { 0x15,0xe8,0xe6,0xef }, - { 0xe7,0x9b,0xd9,0xba }, { 0x6f,0x36,0xce,0x4a }, - { 0x9f,0x09,0xd4,0xea }, { 0xb0,0x7c,0xd6,0x29 }, - { 0xa4,0xb2,0xaf,0x31 }, { 0x3f,0x23,0x31,0x2a }, - { 0xa5,0x94,0x30,0xc6 }, { 0xa2,0x66,0xc0,0x35 }, - { 0x4e,0xbc,0x37,0x74 }, { 0x82,0xca,0xa6,0xfc }, - { 0x90,0xd0,0xb0,0xe0 }, { 0xa7,0xd8,0x15,0x33 }, - { 0x04,0x98,0x4a,0xf1 }, { 0xec,0xda,0xf7,0x41 }, - { 0xcd,0x50,0x0e,0x7f }, { 0x91,0xf6,0x2f,0x17 }, - { 0x4d,0xd6,0x8d,0x76 }, { 0xef,0xb0,0x4d,0x43 }, - { 0xaa,0x4d,0x54,0xcc }, { 0x96,0x04,0xdf,0xe4 }, - { 0xd1,0xb5,0xe3,0x9e }, { 0x6a,0x88,0x1b,0x4c }, - { 0x2c,0x1f,0xb8,0xc1 }, { 0x65,0x51,0x7f,0x46 }, - { 0x5e,0xea,0x04,0x9d }, { 0x8c,0x35,0x5d,0x01 }, - { 0x87,0x74,0x73,0xfa }, { 0x0b,0x41,0x2e,0xfb }, - { 0x67,0x1d,0x5a,0xb3 }, { 0xdb,0xd2,0x52,0x92 }, - { 0x10,0x56,0x33,0xe9 }, { 0xd6,0x47,0x13,0x6d }, - { 0xd7,0x61,0x8c,0x9a }, { 0xa1,0x0c,0x7a,0x37 }, - { 0xf8,0x14,0x8e,0x59 }, { 0x13,0x3c,0x89,0xeb }, - { 0xa9,0x27,0xee,0xce }, { 0x61,0xc9,0x35,0xb7 }, - { 0x1c,0xe5,0xed,0xe1 }, { 0x47,0xb1,0x3c,0x7a }, - { 0xd2,0xdf,0x59,0x9c }, { 0xf2,0x73,0x3f,0x55 }, - { 0x14,0xce,0x79,0x18 }, { 0xc7,0x37,0xbf,0x73 }, - { 0xf7,0xcd,0xea,0x53 }, { 0xfd,0xaa,0x5b,0x5f }, - { 0x3d,0x6f,0x14,0xdf }, { 0x44,0xdb,0x86,0x78 }, - { 0xaf,0xf3,0x81,0xca }, { 0x68,0xc4,0x3e,0xb9 }, - { 0x24,0x34,0x2c,0x38 }, { 0xa3,0x40,0x5f,0xc2 }, - { 0x1d,0xc3,0x72,0x16 }, { 0xe2,0x25,0x0c,0xbc }, - { 0x3c,0x49,0x8b,0x28 }, { 0x0d,0x95,0x41,0xff }, - { 0xa8,0x01,0x71,0x39 }, { 0x0c,0xb3,0xde,0x08 }, - { 0xb4,0xe4,0x9c,0xd8 }, { 0x56,0xc1,0x90,0x64 }, - { 0xcb,0x84,0x61,0x7b }, { 0x32,0xb6,0x70,0xd5 }, - { 0x6c,0x5c,0x74,0x48 }, { 0xb8,0x57,0x42,0xd0 } - }; - -static const unsigned char S5[256] = - { - 0x52,0x09,0x6a,0xd5,0x30,0x36,0xa5,0x38, - 0xbf,0x40,0xa3,0x9e,0x81,0xf3,0xd7,0xfb, - 0x7c,0xe3,0x39,0x82,0x9b,0x2f,0xff,0x87, - 0x34,0x8e,0x43,0x44,0xc4,0xde,0xe9,0xcb, - 0x54,0x7b,0x94,0x32,0xa6,0xc2,0x23,0x3d, - 0xee,0x4c,0x95,0x0b,0x42,0xfa,0xc3,0x4e, - 0x08,0x2e,0xa1,0x66,0x28,0xd9,0x24,0xb2, - 0x76,0x5b,0xa2,0x49,0x6d,0x8b,0xd1,0x25, - 0x72,0xf8,0xf6,0x64,0x86,0x68,0x98,0x16, - 0xd4,0xa4,0x5c,0xcc,0x5d,0x65,0xb6,0x92, - 0x6c,0x70,0x48,0x50,0xfd,0xed,0xb9,0xda, - 0x5e,0x15,0x46,0x57,0xa7,0x8d,0x9d,0x84, - 0x90,0xd8,0xab,0x00,0x8c,0xbc,0xd3,0x0a, - 0xf7,0xe4,0x58,0x05,0xb8,0xb3,0x45,0x06, - 0xd0,0x2c,0x1e,0x8f,0xca,0x3f,0x0f,0x02, - 0xc1,0xaf,0xbd,0x03,0x01,0x13,0x8a,0x6b, - 0x3a,0x91,0x11,0x41,0x4f,0x67,0xdc,0xea, - 0x97,0xf2,0xcf,0xce,0xf0,0xb4,0xe6,0x73, - 0x96,0xac,0x74,0x22,0xe7,0xad,0x35,0x85, - 0xe2,0xf9,0x37,0xe8,0x1c,0x75,0xdf,0x6e, - 0x47,0xf1,0x1a,0x71,0x1d,0x29,0xc5,0x89, - 0x6f,0xb7,0x62,0x0e,0xaa,0x18,0xbe,0x1b, - 0xfc,0x56,0x3e,0x4b,0xc6,0xd2,0x79,0x20, - 0x9a,0xdb,0xc0,0xfe,0x78,0xcd,0x5a,0xf4, - 0x1f,0xdd,0xa8,0x33,0x88,0x07,0xc7,0x31, - 0xb1,0x12,0x10,0x59,0x27,0x80,0xec,0x5f, - 0x60,0x51,0x7f,0xa9,0x19,0xb5,0x4a,0x0d, - 0x2d,0xe5,0x7a,0x9f,0x93,0xc9,0x9c,0xef, - 0xa0,0xe0,0x3b,0x4d,0xae,0x2a,0xf5,0xb0, - 0xc8,0xeb,0xbb,0x3c,0x83,0x53,0x99,0x61, - 0x17,0x2b,0x04,0x7e,0xba,0x77,0xd6,0x26, - 0xe1,0x69,0x14,0x63,0x55,0x21,0x0c,0x7d - }; - -static const unsigned char U1[256][4] = +static const struct +{ + u32 T[256]; + byte inv_sbox[256]; +} dec_tables = { - { 0x00,0x00,0x00,0x00 }, { 0x0e,0x09,0x0d,0x0b }, - { 0x1c,0x12,0x1a,0x16 }, { 0x12,0x1b,0x17,0x1d }, - { 0x38,0x24,0x34,0x2c }, { 0x36,0x2d,0x39,0x27 }, - { 0x24,0x36,0x2e,0x3a }, { 0x2a,0x3f,0x23,0x31 }, - { 0x70,0x48,0x68,0x58 }, { 0x7e,0x41,0x65,0x53 }, - { 0x6c,0x5a,0x72,0x4e }, { 0x62,0x53,0x7f,0x45 }, - { 0x48,0x6c,0x5c,0x74 }, { 0x46,0x65,0x51,0x7f }, - { 0x54,0x7e,0x46,0x62 }, { 0x5a,0x77,0x4b,0x69 }, - { 0xe0,0x90,0xd0,0xb0 }, { 0xee,0x99,0xdd,0xbb }, - { 0xfc,0x82,0xca,0xa6 }, { 0xf2,0x8b,0xc7,0xad }, - { 0xd8,0xb4,0xe4,0x9c }, { 0xd6,0xbd,0xe9,0x97 }, - { 0xc4,0xa6,0xfe,0x8a }, { 0xca,0xaf,0xf3,0x81 }, - { 0x90,0xd8,0xb8,0xe8 }, { 0x9e,0xd1,0xb5,0xe3 }, - { 0x8c,0xca,0xa2,0xfe }, { 0x82,0xc3,0xaf,0xf5 }, - { 0xa8,0xfc,0x8c,0xc4 }, { 0xa6,0xf5,0x81,0xcf }, - { 0xb4,0xee,0x96,0xd2 }, { 0xba,0xe7,0x9b,0xd9 }, - { 0xdb,0x3b,0xbb,0x7b }, { 0xd5,0x32,0xb6,0x70 }, - { 0xc7,0x29,0xa1,0x6d }, { 0xc9,0x20,0xac,0x66 }, - { 0xe3,0x1f,0x8f,0x57 }, { 0xed,0x16,0x82,0x5c }, - { 0xff,0x0d,0x95,0x41 }, { 0xf1,0x04,0x98,0x4a }, - { 0xab,0x73,0xd3,0x23 }, { 0xa5,0x7a,0xde,0x28 }, - { 0xb7,0x61,0xc9,0x35 }, { 0xb9,0x68,0xc4,0x3e }, - { 0x93,0x57,0xe7,0x0f }, { 0x9d,0x5e,0xea,0x04 }, - { 0x8f,0x45,0xfd,0x19 }, { 0x81,0x4c,0xf0,0x12 }, - { 0x3b,0xab,0x6b,0xcb }, { 0x35,0xa2,0x66,0xc0 }, - { 0x27,0xb9,0x71,0xdd }, { 0x29,0xb0,0x7c,0xd6 }, - { 0x03,0x8f,0x5f,0xe7 }, { 0x0d,0x86,0x52,0xec }, - { 0x1f,0x9d,0x45,0xf1 }, { 0x11,0x94,0x48,0xfa }, - { 0x4b,0xe3,0x03,0x93 }, { 0x45,0xea,0x0e,0x98 }, - { 0x57,0xf1,0x19,0x85 }, { 0x59,0xf8,0x14,0x8e }, - { 0x73,0xc7,0x37,0xbf }, { 0x7d,0xce,0x3a,0xb4 }, - { 0x6f,0xd5,0x2d,0xa9 }, { 0x61,0xdc,0x20,0xa2 }, - { 0xad,0x76,0x6d,0xf6 }, { 0xa3,0x7f,0x60,0xfd }, - { 0xb1,0x64,0x77,0xe0 }, { 0xbf,0x6d,0x7a,0xeb }, - { 0x95,0x52,0x59,0xda }, { 0x9b,0x5b,0x54,0xd1 }, - { 0x89,0x40,0x43,0xcc }, { 0x87,0x49,0x4e,0xc7 }, - { 0xdd,0x3e,0x05,0xae }, { 0xd3,0x37,0x08,0xa5 }, - { 0xc1,0x2c,0x1f,0xb8 }, { 0xcf,0x25,0x12,0xb3 }, - { 0xe5,0x1a,0x31,0x82 }, { 0xeb,0x13,0x3c,0x89 }, - { 0xf9,0x08,0x2b,0x94 }, { 0xf7,0x01,0x26,0x9f }, - { 0x4d,0xe6,0xbd,0x46 }, { 0x43,0xef,0xb0,0x4d }, - { 0x51,0xf4,0xa7,0x50 }, { 0x5f,0xfd,0xaa,0x5b }, - { 0x75,0xc2,0x89,0x6a }, { 0x7b,0xcb,0x84,0x61 }, - { 0x69,0xd0,0x93,0x7c }, { 0x67,0xd9,0x9e,0x77 }, - { 0x3d,0xae,0xd5,0x1e }, { 0x33,0xa7,0xd8,0x15 }, - { 0x21,0xbc,0xcf,0x08 }, { 0x2f,0xb5,0xc2,0x03 }, - { 0x05,0x8a,0xe1,0x32 }, { 0x0b,0x83,0xec,0x39 }, - { 0x19,0x98,0xfb,0x24 }, { 0x17,0x91,0xf6,0x2f }, - { 0x76,0x4d,0xd6,0x8d }, { 0x78,0x44,0xdb,0x86 }, - { 0x6a,0x5f,0xcc,0x9b }, { 0x64,0x56,0xc1,0x90 }, - { 0x4e,0x69,0xe2,0xa1 }, { 0x40,0x60,0xef,0xaa }, - { 0x52,0x7b,0xf8,0xb7 }, { 0x5c,0x72,0xf5,0xbc }, - { 0x06,0x05,0xbe,0xd5 }, { 0x08,0x0c,0xb3,0xde }, - { 0x1a,0x17,0xa4,0xc3 }, { 0x14,0x1e,0xa9,0xc8 }, - { 0x3e,0x21,0x8a,0xf9 }, { 0x30,0x28,0x87,0xf2 }, - { 0x22,0x33,0x90,0xef }, { 0x2c,0x3a,0x9d,0xe4 }, - { 0x96,0xdd,0x06,0x3d }, { 0x98,0xd4,0x0b,0x36 }, - { 0x8a,0xcf,0x1c,0x2b }, { 0x84,0xc6,0x11,0x20 }, - { 0xae,0xf9,0x32,0x11 }, { 0xa0,0xf0,0x3f,0x1a }, - { 0xb2,0xeb,0x28,0x07 }, { 0xbc,0xe2,0x25,0x0c }, - { 0xe6,0x95,0x6e,0x65 }, { 0xe8,0x9c,0x63,0x6e }, - { 0xfa,0x87,0x74,0x73 }, { 0xf4,0x8e,0x79,0x78 }, - { 0xde,0xb1,0x5a,0x49 }, { 0xd0,0xb8,0x57,0x42 }, - { 0xc2,0xa3,0x40,0x5f }, { 0xcc,0xaa,0x4d,0x54 }, - { 0x41,0xec,0xda,0xf7 }, { 0x4f,0xe5,0xd7,0xfc }, - { 0x5d,0xfe,0xc0,0xe1 }, { 0x53,0xf7,0xcd,0xea }, - { 0x79,0xc8,0xee,0xdb }, { 0x77,0xc1,0xe3,0xd0 }, - { 0x65,0xda,0xf4,0xcd }, { 0x6b,0xd3,0xf9,0xc6 }, - { 0x31,0xa4,0xb2,0xaf }, { 0x3f,0xad,0xbf,0xa4 }, - { 0x2d,0xb6,0xa8,0xb9 }, { 0x23,0xbf,0xa5,0xb2 }, - { 0x09,0x80,0x86,0x83 }, { 0x07,0x89,0x8b,0x88 }, - { 0x15,0x92,0x9c,0x95 }, { 0x1b,0x9b,0x91,0x9e }, - { 0xa1,0x7c,0x0a,0x47 }, { 0xaf,0x75,0x07,0x4c }, - { 0xbd,0x6e,0x10,0x51 }, { 0xb3,0x67,0x1d,0x5a }, - { 0x99,0x58,0x3e,0x6b }, { 0x97,0x51,0x33,0x60 }, - { 0x85,0x4a,0x24,0x7d }, { 0x8b,0x43,0x29,0x76 }, - { 0xd1,0x34,0x62,0x1f }, { 0xdf,0x3d,0x6f,0x14 }, - { 0xcd,0x26,0x78,0x09 }, { 0xc3,0x2f,0x75,0x02 }, - { 0xe9,0x10,0x56,0x33 }, { 0xe7,0x19,0x5b,0x38 }, - { 0xf5,0x02,0x4c,0x25 }, { 0xfb,0x0b,0x41,0x2e }, - { 0x9a,0xd7,0x61,0x8c }, { 0x94,0xde,0x6c,0x87 }, - { 0x86,0xc5,0x7b,0x9a }, { 0x88,0xcc,0x76,0x91 }, - { 0xa2,0xf3,0x55,0xa0 }, { 0xac,0xfa,0x58,0xab }, - { 0xbe,0xe1,0x4f,0xb6 }, { 0xb0,0xe8,0x42,0xbd }, - { 0xea,0x9f,0x09,0xd4 }, { 0xe4,0x96,0x04,0xdf }, - { 0xf6,0x8d,0x13,0xc2 }, { 0xf8,0x84,0x1e,0xc9 }, - { 0xd2,0xbb,0x3d,0xf8 }, { 0xdc,0xb2,0x30,0xf3 }, - { 0xce,0xa9,0x27,0xee }, { 0xc0,0xa0,0x2a,0xe5 }, - { 0x7a,0x47,0xb1,0x3c }, { 0x74,0x4e,0xbc,0x37 }, - { 0x66,0x55,0xab,0x2a }, { 0x68,0x5c,0xa6,0x21 }, - { 0x42,0x63,0x85,0x10 }, { 0x4c,0x6a,0x88,0x1b }, - { 0x5e,0x71,0x9f,0x06 }, { 0x50,0x78,0x92,0x0d }, - { 0x0a,0x0f,0xd9,0x64 }, { 0x04,0x06,0xd4,0x6f }, - { 0x16,0x1d,0xc3,0x72 }, { 0x18,0x14,0xce,0x79 }, - { 0x32,0x2b,0xed,0x48 }, { 0x3c,0x22,0xe0,0x43 }, - { 0x2e,0x39,0xf7,0x5e }, { 0x20,0x30,0xfa,0x55 }, - { 0xec,0x9a,0xb7,0x01 }, { 0xe2,0x93,0xba,0x0a }, - { 0xf0,0x88,0xad,0x17 }, { 0xfe,0x81,0xa0,0x1c }, - { 0xd4,0xbe,0x83,0x2d }, { 0xda,0xb7,0x8e,0x26 }, - { 0xc8,0xac,0x99,0x3b }, { 0xc6,0xa5,0x94,0x30 }, - { 0x9c,0xd2,0xdf,0x59 }, { 0x92,0xdb,0xd2,0x52 }, - { 0x80,0xc0,0xc5,0x4f }, { 0x8e,0xc9,0xc8,0x44 }, - { 0xa4,0xf6,0xeb,0x75 }, { 0xaa,0xff,0xe6,0x7e }, - { 0xb8,0xe4,0xf1,0x63 }, { 0xb6,0xed,0xfc,0x68 }, - { 0x0c,0x0a,0x67,0xb1 }, { 0x02,0x03,0x6a,0xba }, - { 0x10,0x18,0x7d,0xa7 }, { 0x1e,0x11,0x70,0xac }, - { 0x34,0x2e,0x53,0x9d }, { 0x3a,0x27,0x5e,0x96 }, - { 0x28,0x3c,0x49,0x8b }, { 0x26,0x35,0x44,0x80 }, - { 0x7c,0x42,0x0f,0xe9 }, { 0x72,0x4b,0x02,0xe2 }, - { 0x60,0x50,0x15,0xff }, { 0x6e,0x59,0x18,0xf4 }, - { 0x44,0x66,0x3b,0xc5 }, { 0x4a,0x6f,0x36,0xce }, - { 0x58,0x74,0x21,0xd3 }, { 0x56,0x7d,0x2c,0xd8 }, - { 0x37,0xa1,0x0c,0x7a }, { 0x39,0xa8,0x01,0x71 }, - { 0x2b,0xb3,0x16,0x6c }, { 0x25,0xba,0x1b,0x67 }, - { 0x0f,0x85,0x38,0x56 }, { 0x01,0x8c,0x35,0x5d }, - { 0x13,0x97,0x22,0x40 }, { 0x1d,0x9e,0x2f,0x4b }, - { 0x47,0xe9,0x64,0x22 }, { 0x49,0xe0,0x69,0x29 }, - { 0x5b,0xfb,0x7e,0x34 }, { 0x55,0xf2,0x73,0x3f }, - { 0x7f,0xcd,0x50,0x0e }, { 0x71,0xc4,0x5d,0x05 }, - { 0x63,0xdf,0x4a,0x18 }, { 0x6d,0xd6,0x47,0x13 }, - { 0xd7,0x31,0xdc,0xca }, { 0xd9,0x38,0xd1,0xc1 }, - { 0xcb,0x23,0xc6,0xdc }, { 0xc5,0x2a,0xcb,0xd7 }, - { 0xef,0x15,0xe8,0xe6 }, { 0xe1,0x1c,0xe5,0xed }, - { 0xf3,0x07,0xf2,0xf0 }, { 0xfd,0x0e,0xff,0xfb }, - { 0xa7,0x79,0xb4,0x92 }, { 0xa9,0x70,0xb9,0x99 }, - { 0xbb,0x6b,0xae,0x84 }, { 0xb5,0x62,0xa3,0x8f }, - { 0x9f,0x5d,0x80,0xbe }, { 0x91,0x54,0x8d,0xb5 }, - { 0x83,0x4f,0x9a,0xa8 }, { 0x8d,0x46,0x97,0xa3 } + { + 0x50a7f451, 0x5365417e, 0xc3a4171a, 0x965e273a, + 0xcb6bab3b, 0xf1459d1f, 0xab58faac, 0x9303e34b, + 0x55fa3020, 0xf66d76ad, 0x9176cc88, 0x254c02f5, + 0xfcd7e54f, 0xd7cb2ac5, 0x80443526, 0x8fa362b5, + 0x495ab1de, 0x671bba25, 0x980eea45, 0xe1c0fe5d, + 0x02752fc3, 0x12f04c81, 0xa397468d, 0xc6f9d36b, + 0xe75f8f03, 0x959c9215, 0xeb7a6dbf, 0xda595295, + 0x2d83bed4, 0xd3217458, 0x2969e049, 0x44c8c98e, + 0x6a89c275, 0x78798ef4, 0x6b3e5899, 0xdd71b927, + 0xb64fe1be, 0x17ad88f0, 0x66ac20c9, 0xb43ace7d, + 0x184adf63, 0x82311ae5, 0x60335197, 0x457f5362, + 0xe07764b1, 0x84ae6bbb, 0x1ca081fe, 0x942b08f9, + 0x58684870, 0x19fd458f, 0x876cde94, 0xb7f87b52, + 0x23d373ab, 0xe2024b72, 0x578f1fe3, 0x2aab5566, + 0x0728ebb2, 0x03c2b52f, 0x9a7bc586, 0xa50837d3, + 0xf2872830, 0xb2a5bf23, 0xba6a0302, 0x5c8216ed, + 0x2b1ccf8a, 0x92b479a7, 0xf0f207f3, 0xa1e2694e, + 0xcdf4da65, 0xd5be0506, 0x1f6234d1, 0x8afea6c4, + 0x9d532e34, 0xa055f3a2, 0x32e18a05, 0x75ebf6a4, + 0x39ec830b, 0xaaef6040, 0x069f715e, 0x51106ebd, + 0xf98a213e, 0x3d06dd96, 0xae053edd, 0x46bde64d, + 0xb58d5491, 0x055dc471, 0x6fd40604, 0xff155060, + 0x24fb9819, 0x97e9bdd6, 0xcc434089, 0x779ed967, + 0xbd42e8b0, 0x888b8907, 0x385b19e7, 0xdbeec879, + 0x470a7ca1, 0xe90f427c, 0xc91e84f8, 0x00000000, + 0x83868009, 0x48ed2b32, 0xac70111e, 0x4e725a6c, + 0xfbff0efd, 0x5638850f, 0x1ed5ae3d, 0x27392d36, + 0x64d90f0a, 0x21a65c68, 0xd1545b9b, 0x3a2e3624, + 0xb1670a0c, 0x0fe75793, 0xd296eeb4, 0x9e919b1b, + 0x4fc5c080, 0xa220dc61, 0x694b775a, 0x161a121c, + 0x0aba93e2, 0xe52aa0c0, 0x43e0223c, 0x1d171b12, + 0x0b0d090e, 0xadc78bf2, 0xb9a8b62d, 0xc8a91e14, + 0x8519f157, 0x4c0775af, 0xbbdd99ee, 0xfd607fa3, + 0x9f2601f7, 0xbcf5725c, 0xc53b6644, 0x347efb5b, + 0x7629438b, 0xdcc623cb, 0x68fcedb6, 0x63f1e4b8, + 0xcadc31d7, 0x10856342, 0x40229713, 0x2011c684, + 0x7d244a85, 0xf83dbbd2, 0x1132f9ae, 0x6da129c7, + 0x4b2f9e1d, 0xf330b2dc, 0xec52860d, 0xd0e3c177, + 0x6c16b32b, 0x99b970a9, 0xfa489411, 0x2264e947, + 0xc48cfca8, 0x1a3ff0a0, 0xd82c7d56, 0xef903322, + 0xc74e4987, 0xc1d138d9, 0xfea2ca8c, 0x360bd498, + 0xcf81f5a6, 0x28de7aa5, 0x268eb7da, 0xa4bfad3f, + 0xe49d3a2c, 0x0d927850, 0x9bcc5f6a, 0x62467e54, + 0xc2138df6, 0xe8b8d890, 0x5ef7392e, 0xf5afc382, + 0xbe805d9f, 0x7c93d069, 0xa92dd56f, 0xb31225cf, + 0x3b99acc8, 0xa77d1810, 0x6e639ce8, 0x7bbb3bdb, + 0x097826cd, 0xf418596e, 0x01b79aec, 0xa89a4f83, + 0x656e95e6, 0x7ee6ffaa, 0x08cfbc21, 0xe6e815ef, + 0xd99be7ba, 0xce366f4a, 0xd4099fea, 0xd67cb029, + 0xafb2a431, 0x31233f2a, 0x3094a5c6, 0xc066a235, + 0x37bc4e74, 0xa6ca82fc, 0xb0d090e0, 0x15d8a733, + 0x4a9804f1, 0xf7daec41, 0x0e50cd7f, 0x2ff69117, + 0x8dd64d76, 0x4db0ef43, 0x544daacc, 0xdf0496e4, + 0xe3b5d19e, 0x1b886a4c, 0xb81f2cc1, 0x7f516546, + 0x04ea5e9d, 0x5d358c01, 0x737487fa, 0x2e410bfb, + 0x5a1d67b3, 0x52d2db92, 0x335610e9, 0x1347d66d, + 0x8c61d79a, 0x7a0ca137, 0x8e14f859, 0x893c13eb, + 0xee27a9ce, 0x35c961b7, 0xede51ce1, 0x3cb1477a, + 0x59dfd29c, 0x3f73f255, 0x79ce1418, 0xbf37c773, + 0xeacdf753, 0x5baafd5f, 0x146f3ddf, 0x86db4478, + 0x81f3afca, 0x3ec468b9, 0x2c342438, 0x5f40a3c2, + 0x72c31d16, 0x0c25e2bc, 0x8b493c28, 0x41950dff, + 0x7101a839, 0xdeb30c08, 0x9ce4b4d8, 0x90c15664, + 0x6184cb7b, 0x70b632d5, 0x745c6c48, 0x4257b8d0 + }, + { + 0x52,0x09,0x6a,0xd5,0x30,0x36,0xa5,0x38, + 0xbf,0x40,0xa3,0x9e,0x81,0xf3,0xd7,0xfb, + 0x7c,0xe3,0x39,0x82,0x9b,0x2f,0xff,0x87, + 0x34,0x8e,0x43,0x44,0xc4,0xde,0xe9,0xcb, + 0x54,0x7b,0x94,0x32,0xa6,0xc2,0x23,0x3d, + 0xee,0x4c,0x95,0x0b,0x42,0xfa,0xc3,0x4e, + 0x08,0x2e,0xa1,0x66,0x28,0xd9,0x24,0xb2, + 0x76,0x5b,0xa2,0x49,0x6d,0x8b,0xd1,0x25, + 0x72,0xf8,0xf6,0x64,0x86,0x68,0x98,0x16, + 0xd4,0xa4,0x5c,0xcc,0x5d,0x65,0xb6,0x92, + 0x6c,0x70,0x48,0x50,0xfd,0xed,0xb9,0xda, + 0x5e,0x15,0x46,0x57,0xa7,0x8d,0x9d,0x84, + 0x90,0xd8,0xab,0x00,0x8c,0xbc,0xd3,0x0a, + 0xf7,0xe4,0x58,0x05,0xb8,0xb3,0x45,0x06, + 0xd0,0x2c,0x1e,0x8f,0xca,0x3f,0x0f,0x02, + 0xc1,0xaf,0xbd,0x03,0x01,0x13,0x8a,0x6b, + 0x3a,0x91,0x11,0x41,0x4f,0x67,0xdc,0xea, + 0x97,0xf2,0xcf,0xce,0xf0,0xb4,0xe6,0x73, + 0x96,0xac,0x74,0x22,0xe7,0xad,0x35,0x85, + 0xe2,0xf9,0x37,0xe8,0x1c,0x75,0xdf,0x6e, + 0x47,0xf1,0x1a,0x71,0x1d,0x29,0xc5,0x89, + 0x6f,0xb7,0x62,0x0e,0xaa,0x18,0xbe,0x1b, + 0xfc,0x56,0x3e,0x4b,0xc6,0xd2,0x79,0x20, + 0x9a,0xdb,0xc0,0xfe,0x78,0xcd,0x5a,0xf4, + 0x1f,0xdd,0xa8,0x33,0x88,0x07,0xc7,0x31, + 0xb1,0x12,0x10,0x59,0x27,0x80,0xec,0x5f, + 0x60,0x51,0x7f,0xa9,0x19,0xb5,0x4a,0x0d, + 0x2d,0xe5,0x7a,0x9f,0x93,0xc9,0x9c,0xef, + 0xa0,0xe0,0x3b,0x4d,0xae,0x2a,0xf5,0xb0, + 0xc8,0xeb,0xbb,0x3c,0x83,0x53,0x99,0x61, + 0x17,0x2b,0x04,0x7e,0xba,0x77,0xd6,0x26, + 0xe1,0x69,0x14,0x63,0x55,0x21,0x0c,0x7d + } }; -static const unsigned char U2[256][4] = - { - { 0x00,0x00,0x00,0x00 }, { 0x0b,0x0e,0x09,0x0d }, - { 0x16,0x1c,0x12,0x1a }, { 0x1d,0x12,0x1b,0x17 }, - { 0x2c,0x38,0x24,0x34 }, { 0x27,0x36,0x2d,0x39 }, - { 0x3a,0x24,0x36,0x2e }, { 0x31,0x2a,0x3f,0x23 }, - { 0x58,0x70,0x48,0x68 }, { 0x53,0x7e,0x41,0x65 }, - { 0x4e,0x6c,0x5a,0x72 }, { 0x45,0x62,0x53,0x7f }, - { 0x74,0x48,0x6c,0x5c }, { 0x7f,0x46,0x65,0x51 }, - { 0x62,0x54,0x7e,0x46 }, { 0x69,0x5a,0x77,0x4b }, - { 0xb0,0xe0,0x90,0xd0 }, { 0xbb,0xee,0x99,0xdd }, - { 0xa6,0xfc,0x82,0xca }, { 0xad,0xf2,0x8b,0xc7 }, - { 0x9c,0xd8,0xb4,0xe4 }, { 0x97,0xd6,0xbd,0xe9 }, - { 0x8a,0xc4,0xa6,0xfe }, { 0x81,0xca,0xaf,0xf3 }, - { 0xe8,0x90,0xd8,0xb8 }, { 0xe3,0x9e,0xd1,0xb5 }, - { 0xfe,0x8c,0xca,0xa2 }, { 0xf5,0x82,0xc3,0xaf }, - { 0xc4,0xa8,0xfc,0x8c }, { 0xcf,0xa6,0xf5,0x81 }, - { 0xd2,0xb4,0xee,0x96 }, { 0xd9,0xba,0xe7,0x9b }, - { 0x7b,0xdb,0x3b,0xbb }, { 0x70,0xd5,0x32,0xb6 }, - { 0x6d,0xc7,0x29,0xa1 }, { 0x66,0xc9,0x20,0xac }, - { 0x57,0xe3,0x1f,0x8f }, { 0x5c,0xed,0x16,0x82 }, - { 0x41,0xff,0x0d,0x95 }, { 0x4a,0xf1,0x04,0x98 }, - { 0x23,0xab,0x73,0xd3 }, { 0x28,0xa5,0x7a,0xde }, - { 0x35,0xb7,0x61,0xc9 }, { 0x3e,0xb9,0x68,0xc4 }, - { 0x0f,0x93,0x57,0xe7 }, { 0x04,0x9d,0x5e,0xea }, - { 0x19,0x8f,0x45,0xfd }, { 0x12,0x81,0x4c,0xf0 }, - { 0xcb,0x3b,0xab,0x6b }, { 0xc0,0x35,0xa2,0x66 }, - { 0xdd,0x27,0xb9,0x71 }, { 0xd6,0x29,0xb0,0x7c }, - { 0xe7,0x03,0x8f,0x5f }, { 0xec,0x0d,0x86,0x52 }, - { 0xf1,0x1f,0x9d,0x45 }, { 0xfa,0x11,0x94,0x48 }, - { 0x93,0x4b,0xe3,0x03 }, { 0x98,0x45,0xea,0x0e }, - { 0x85,0x57,0xf1,0x19 }, { 0x8e,0x59,0xf8,0x14 }, - { 0xbf,0x73,0xc7,0x37 }, { 0xb4,0x7d,0xce,0x3a }, - { 0xa9,0x6f,0xd5,0x2d }, { 0xa2,0x61,0xdc,0x20 }, - { 0xf6,0xad,0x76,0x6d }, { 0xfd,0xa3,0x7f,0x60 }, - { 0xe0,0xb1,0x64,0x77 }, { 0xeb,0xbf,0x6d,0x7a }, - { 0xda,0x95,0x52,0x59 }, { 0xd1,0x9b,0x5b,0x54 }, - { 0xcc,0x89,0x40,0x43 }, { 0xc7,0x87,0x49,0x4e }, - { 0xae,0xdd,0x3e,0x05 }, { 0xa5,0xd3,0x37,0x08 }, - { 0xb8,0xc1,0x2c,0x1f }, { 0xb3,0xcf,0x25,0x12 }, - { 0x82,0xe5,0x1a,0x31 }, { 0x89,0xeb,0x13,0x3c }, - { 0x94,0xf9,0x08,0x2b }, { 0x9f,0xf7,0x01,0x26 }, - { 0x46,0x4d,0xe6,0xbd }, { 0x4d,0x43,0xef,0xb0 }, - { 0x50,0x51,0xf4,0xa7 }, { 0x5b,0x5f,0xfd,0xaa }, - { 0x6a,0x75,0xc2,0x89 }, { 0x61,0x7b,0xcb,0x84 }, - { 0x7c,0x69,0xd0,0x93 }, { 0x77,0x67,0xd9,0x9e }, - { 0x1e,0x3d,0xae,0xd5 }, { 0x15,0x33,0xa7,0xd8 }, - { 0x08,0x21,0xbc,0xcf }, { 0x03,0x2f,0xb5,0xc2 }, - { 0x32,0x05,0x8a,0xe1 }, { 0x39,0x0b,0x83,0xec }, - { 0x24,0x19,0x98,0xfb }, { 0x2f,0x17,0x91,0xf6 }, - { 0x8d,0x76,0x4d,0xd6 }, { 0x86,0x78,0x44,0xdb }, - { 0x9b,0x6a,0x5f,0xcc }, { 0x90,0x64,0x56,0xc1 }, - { 0xa1,0x4e,0x69,0xe2 }, { 0xaa,0x40,0x60,0xef }, - { 0xb7,0x52,0x7b,0xf8 }, { 0xbc,0x5c,0x72,0xf5 }, - { 0xd5,0x06,0x05,0xbe }, { 0xde,0x08,0x0c,0xb3 }, - { 0xc3,0x1a,0x17,0xa4 }, { 0xc8,0x14,0x1e,0xa9 }, - { 0xf9,0x3e,0x21,0x8a }, { 0xf2,0x30,0x28,0x87 }, - { 0xef,0x22,0x33,0x90 }, { 0xe4,0x2c,0x3a,0x9d }, - { 0x3d,0x96,0xdd,0x06 }, { 0x36,0x98,0xd4,0x0b }, - { 0x2b,0x8a,0xcf,0x1c }, { 0x20,0x84,0xc6,0x11 }, - { 0x11,0xae,0xf9,0x32 }, { 0x1a,0xa0,0xf0,0x3f }, - { 0x07,0xb2,0xeb,0x28 }, { 0x0c,0xbc,0xe2,0x25 }, - { 0x65,0xe6,0x95,0x6e }, { 0x6e,0xe8,0x9c,0x63 }, - { 0x73,0xfa,0x87,0x74 }, { 0x78,0xf4,0x8e,0x79 }, - { 0x49,0xde,0xb1,0x5a }, { 0x42,0xd0,0xb8,0x57 }, - { 0x5f,0xc2,0xa3,0x40 }, { 0x54,0xcc,0xaa,0x4d }, - { 0xf7,0x41,0xec,0xda }, { 0xfc,0x4f,0xe5,0xd7 }, - { 0xe1,0x5d,0xfe,0xc0 }, { 0xea,0x53,0xf7,0xcd }, - { 0xdb,0x79,0xc8,0xee }, { 0xd0,0x77,0xc1,0xe3 }, - { 0xcd,0x65,0xda,0xf4 }, { 0xc6,0x6b,0xd3,0xf9 }, - { 0xaf,0x31,0xa4,0xb2 }, { 0xa4,0x3f,0xad,0xbf }, - { 0xb9,0x2d,0xb6,0xa8 }, { 0xb2,0x23,0xbf,0xa5 }, - { 0x83,0x09,0x80,0x86 }, { 0x88,0x07,0x89,0x8b }, - { 0x95,0x15,0x92,0x9c }, { 0x9e,0x1b,0x9b,0x91 }, - { 0x47,0xa1,0x7c,0x0a }, { 0x4c,0xaf,0x75,0x07 }, - { 0x51,0xbd,0x6e,0x10 }, { 0x5a,0xb3,0x67,0x1d }, - { 0x6b,0x99,0x58,0x3e }, { 0x60,0x97,0x51,0x33 }, - { 0x7d,0x85,0x4a,0x24 }, { 0x76,0x8b,0x43,0x29 }, - { 0x1f,0xd1,0x34,0x62 }, { 0x14,0xdf,0x3d,0x6f }, - { 0x09,0xcd,0x26,0x78 }, { 0x02,0xc3,0x2f,0x75 }, - { 0x33,0xe9,0x10,0x56 }, { 0x38,0xe7,0x19,0x5b }, - { 0x25,0xf5,0x02,0x4c }, { 0x2e,0xfb,0x0b,0x41 }, - { 0x8c,0x9a,0xd7,0x61 }, { 0x87,0x94,0xde,0x6c }, - { 0x9a,0x86,0xc5,0x7b }, { 0x91,0x88,0xcc,0x76 }, - { 0xa0,0xa2,0xf3,0x55 }, { 0xab,0xac,0xfa,0x58 }, - { 0xb6,0xbe,0xe1,0x4f }, { 0xbd,0xb0,0xe8,0x42 }, - { 0xd4,0xea,0x9f,0x09 }, { 0xdf,0xe4,0x96,0x04 }, - { 0xc2,0xf6,0x8d,0x13 }, { 0xc9,0xf8,0x84,0x1e }, - { 0xf8,0xd2,0xbb,0x3d }, { 0xf3,0xdc,0xb2,0x30 }, - { 0xee,0xce,0xa9,0x27 }, { 0xe5,0xc0,0xa0,0x2a }, - { 0x3c,0x7a,0x47,0xb1 }, { 0x37,0x74,0x4e,0xbc }, - { 0x2a,0x66,0x55,0xab }, { 0x21,0x68,0x5c,0xa6 }, - { 0x10,0x42,0x63,0x85 }, { 0x1b,0x4c,0x6a,0x88 }, - { 0x06,0x5e,0x71,0x9f }, { 0x0d,0x50,0x78,0x92 }, - { 0x64,0x0a,0x0f,0xd9 }, { 0x6f,0x04,0x06,0xd4 }, - { 0x72,0x16,0x1d,0xc3 }, { 0x79,0x18,0x14,0xce }, - { 0x48,0x32,0x2b,0xed }, { 0x43,0x3c,0x22,0xe0 }, - { 0x5e,0x2e,0x39,0xf7 }, { 0x55,0x20,0x30,0xfa }, - { 0x01,0xec,0x9a,0xb7 }, { 0x0a,0xe2,0x93,0xba }, - { 0x17,0xf0,0x88,0xad }, { 0x1c,0xfe,0x81,0xa0 }, - { 0x2d,0xd4,0xbe,0x83 }, { 0x26,0xda,0xb7,0x8e }, - { 0x3b,0xc8,0xac,0x99 }, { 0x30,0xc6,0xa5,0x94 }, - { 0x59,0x9c,0xd2,0xdf }, { 0x52,0x92,0xdb,0xd2 }, - { 0x4f,0x80,0xc0,0xc5 }, { 0x44,0x8e,0xc9,0xc8 }, - { 0x75,0xa4,0xf6,0xeb }, { 0x7e,0xaa,0xff,0xe6 }, - { 0x63,0xb8,0xe4,0xf1 }, { 0x68,0xb6,0xed,0xfc }, - { 0xb1,0x0c,0x0a,0x67 }, { 0xba,0x02,0x03,0x6a }, - { 0xa7,0x10,0x18,0x7d }, { 0xac,0x1e,0x11,0x70 }, - { 0x9d,0x34,0x2e,0x53 }, { 0x96,0x3a,0x27,0x5e }, - { 0x8b,0x28,0x3c,0x49 }, { 0x80,0x26,0x35,0x44 }, - { 0xe9,0x7c,0x42,0x0f }, { 0xe2,0x72,0x4b,0x02 }, - { 0xff,0x60,0x50,0x15 }, { 0xf4,0x6e,0x59,0x18 }, - { 0xc5,0x44,0x66,0x3b }, { 0xce,0x4a,0x6f,0x36 }, - { 0xd3,0x58,0x74,0x21 }, { 0xd8,0x56,0x7d,0x2c }, - { 0x7a,0x37,0xa1,0x0c }, { 0x71,0x39,0xa8,0x01 }, - { 0x6c,0x2b,0xb3,0x16 }, { 0x67,0x25,0xba,0x1b }, - { 0x56,0x0f,0x85,0x38 }, { 0x5d,0x01,0x8c,0x35 }, - { 0x40,0x13,0x97,0x22 }, { 0x4b,0x1d,0x9e,0x2f }, - { 0x22,0x47,0xe9,0x64 }, { 0x29,0x49,0xe0,0x69 }, - { 0x34,0x5b,0xfb,0x7e }, { 0x3f,0x55,0xf2,0x73 }, - { 0x0e,0x7f,0xcd,0x50 }, { 0x05,0x71,0xc4,0x5d }, - { 0x18,0x63,0xdf,0x4a }, { 0x13,0x6d,0xd6,0x47 }, - { 0xca,0xd7,0x31,0xdc }, { 0xc1,0xd9,0x38,0xd1 }, - { 0xdc,0xcb,0x23,0xc6 }, { 0xd7,0xc5,0x2a,0xcb }, - { 0xe6,0xef,0x15,0xe8 }, { 0xed,0xe1,0x1c,0xe5 }, - { 0xf0,0xf3,0x07,0xf2 }, { 0xfb,0xfd,0x0e,0xff }, - { 0x92,0xa7,0x79,0xb4 }, { 0x99,0xa9,0x70,0xb9 }, - { 0x84,0xbb,0x6b,0xae }, { 0x8f,0xb5,0x62,0xa3 }, - { 0xbe,0x9f,0x5d,0x80 }, { 0xb5,0x91,0x54,0x8d }, - { 0xa8,0x83,0x4f,0x9a }, { 0xa3,0x8d,0x46,0x97 } - }; - -static const unsigned char U3[256][4] = - { - { 0x00,0x00,0x00,0x00 }, { 0x0d,0x0b,0x0e,0x09 }, - { 0x1a,0x16,0x1c,0x12 }, { 0x17,0x1d,0x12,0x1b }, - { 0x34,0x2c,0x38,0x24 }, { 0x39,0x27,0x36,0x2d }, - { 0x2e,0x3a,0x24,0x36 }, { 0x23,0x31,0x2a,0x3f }, - { 0x68,0x58,0x70,0x48 }, { 0x65,0x53,0x7e,0x41 }, - { 0x72,0x4e,0x6c,0x5a }, { 0x7f,0x45,0x62,0x53 }, - { 0x5c,0x74,0x48,0x6c }, { 0x51,0x7f,0x46,0x65 }, - { 0x46,0x62,0x54,0x7e }, { 0x4b,0x69,0x5a,0x77 }, - { 0xd0,0xb0,0xe0,0x90 }, { 0xdd,0xbb,0xee,0x99 }, - { 0xca,0xa6,0xfc,0x82 }, { 0xc7,0xad,0xf2,0x8b }, - { 0xe4,0x9c,0xd8,0xb4 }, { 0xe9,0x97,0xd6,0xbd }, - { 0xfe,0x8a,0xc4,0xa6 }, { 0xf3,0x81,0xca,0xaf }, - { 0xb8,0xe8,0x90,0xd8 }, { 0xb5,0xe3,0x9e,0xd1 }, - { 0xa2,0xfe,0x8c,0xca }, { 0xaf,0xf5,0x82,0xc3 }, - { 0x8c,0xc4,0xa8,0xfc }, { 0x81,0xcf,0xa6,0xf5 }, - { 0x96,0xd2,0xb4,0xee }, { 0x9b,0xd9,0xba,0xe7 }, - { 0xbb,0x7b,0xdb,0x3b }, { 0xb6,0x70,0xd5,0x32 }, - { 0xa1,0x6d,0xc7,0x29 }, { 0xac,0x66,0xc9,0x20 }, - { 0x8f,0x57,0xe3,0x1f }, { 0x82,0x5c,0xed,0x16 }, - { 0x95,0x41,0xff,0x0d }, { 0x98,0x4a,0xf1,0x04 }, - { 0xd3,0x23,0xab,0x73 }, { 0xde,0x28,0xa5,0x7a }, - { 0xc9,0x35,0xb7,0x61 }, { 0xc4,0x3e,0xb9,0x68 }, - { 0xe7,0x0f,0x93,0x57 }, { 0xea,0x04,0x9d,0x5e }, - { 0xfd,0x19,0x8f,0x45 }, { 0xf0,0x12,0x81,0x4c }, - { 0x6b,0xcb,0x3b,0xab }, { 0x66,0xc0,0x35,0xa2 }, - { 0x71,0xdd,0x27,0xb9 }, { 0x7c,0xd6,0x29,0xb0 }, - { 0x5f,0xe7,0x03,0x8f }, { 0x52,0xec,0x0d,0x86 }, - { 0x45,0xf1,0x1f,0x9d }, { 0x48,0xfa,0x11,0x94 }, - { 0x03,0x93,0x4b,0xe3 }, { 0x0e,0x98,0x45,0xea }, - { 0x19,0x85,0x57,0xf1 }, { 0x14,0x8e,0x59,0xf8 }, - { 0x37,0xbf,0x73,0xc7 }, { 0x3a,0xb4,0x7d,0xce }, - { 0x2d,0xa9,0x6f,0xd5 }, { 0x20,0xa2,0x61,0xdc }, - { 0x6d,0xf6,0xad,0x76 }, { 0x60,0xfd,0xa3,0x7f }, - { 0x77,0xe0,0xb1,0x64 }, { 0x7a,0xeb,0xbf,0x6d }, - { 0x59,0xda,0x95,0x52 }, { 0x54,0xd1,0x9b,0x5b }, - { 0x43,0xcc,0x89,0x40 }, { 0x4e,0xc7,0x87,0x49 }, - { 0x05,0xae,0xdd,0x3e }, { 0x08,0xa5,0xd3,0x37 }, - { 0x1f,0xb8,0xc1,0x2c }, { 0x12,0xb3,0xcf,0x25 }, - { 0x31,0x82,0xe5,0x1a }, { 0x3c,0x89,0xeb,0x13 }, - { 0x2b,0x94,0xf9,0x08 }, { 0x26,0x9f,0xf7,0x01 }, - { 0xbd,0x46,0x4d,0xe6 }, { 0xb0,0x4d,0x43,0xef }, - { 0xa7,0x50,0x51,0xf4 }, { 0xaa,0x5b,0x5f,0xfd }, - { 0x89,0x6a,0x75,0xc2 }, { 0x84,0x61,0x7b,0xcb }, - { 0x93,0x7c,0x69,0xd0 }, { 0x9e,0x77,0x67,0xd9 }, - { 0xd5,0x1e,0x3d,0xae }, { 0xd8,0x15,0x33,0xa7 }, - { 0xcf,0x08,0x21,0xbc }, { 0xc2,0x03,0x2f,0xb5 }, - { 0xe1,0x32,0x05,0x8a }, { 0xec,0x39,0x0b,0x83 }, - { 0xfb,0x24,0x19,0x98 }, { 0xf6,0x2f,0x17,0x91 }, - { 0xd6,0x8d,0x76,0x4d }, { 0xdb,0x86,0x78,0x44 }, - { 0xcc,0x9b,0x6a,0x5f }, { 0xc1,0x90,0x64,0x56 }, - { 0xe2,0xa1,0x4e,0x69 }, { 0xef,0xaa,0x40,0x60 }, - { 0xf8,0xb7,0x52,0x7b }, { 0xf5,0xbc,0x5c,0x72 }, - { 0xbe,0xd5,0x06,0x05 }, { 0xb3,0xde,0x08,0x0c }, - { 0xa4,0xc3,0x1a,0x17 }, { 0xa9,0xc8,0x14,0x1e }, - { 0x8a,0xf9,0x3e,0x21 }, { 0x87,0xf2,0x30,0x28 }, - { 0x90,0xef,0x22,0x33 }, { 0x9d,0xe4,0x2c,0x3a }, - { 0x06,0x3d,0x96,0xdd }, { 0x0b,0x36,0x98,0xd4 }, - { 0x1c,0x2b,0x8a,0xcf }, { 0x11,0x20,0x84,0xc6 }, - { 0x32,0x11,0xae,0xf9 }, { 0x3f,0x1a,0xa0,0xf0 }, - { 0x28,0x07,0xb2,0xeb }, { 0x25,0x0c,0xbc,0xe2 }, - { 0x6e,0x65,0xe6,0x95 }, { 0x63,0x6e,0xe8,0x9c }, - { 0x74,0x73,0xfa,0x87 }, { 0x79,0x78,0xf4,0x8e }, - { 0x5a,0x49,0xde,0xb1 }, { 0x57,0x42,0xd0,0xb8 }, - { 0x40,0x5f,0xc2,0xa3 }, { 0x4d,0x54,0xcc,0xaa }, - { 0xda,0xf7,0x41,0xec }, { 0xd7,0xfc,0x4f,0xe5 }, - { 0xc0,0xe1,0x5d,0xfe }, { 0xcd,0xea,0x53,0xf7 }, - { 0xee,0xdb,0x79,0xc8 }, { 0xe3,0xd0,0x77,0xc1 }, - { 0xf4,0xcd,0x65,0xda }, { 0xf9,0xc6,0x6b,0xd3 }, - { 0xb2,0xaf,0x31,0xa4 }, { 0xbf,0xa4,0x3f,0xad }, - { 0xa8,0xb9,0x2d,0xb6 }, { 0xa5,0xb2,0x23,0xbf }, - { 0x86,0x83,0x09,0x80 }, { 0x8b,0x88,0x07,0x89 }, - { 0x9c,0x95,0x15,0x92 }, { 0x91,0x9e,0x1b,0x9b }, - { 0x0a,0x47,0xa1,0x7c }, { 0x07,0x4c,0xaf,0x75 }, - { 0x10,0x51,0xbd,0x6e }, { 0x1d,0x5a,0xb3,0x67 }, - { 0x3e,0x6b,0x99,0x58 }, { 0x33,0x60,0x97,0x51 }, - { 0x24,0x7d,0x85,0x4a }, { 0x29,0x76,0x8b,0x43 }, - { 0x62,0x1f,0xd1,0x34 }, { 0x6f,0x14,0xdf,0x3d }, - { 0x78,0x09,0xcd,0x26 }, { 0x75,0x02,0xc3,0x2f }, - { 0x56,0x33,0xe9,0x10 }, { 0x5b,0x38,0xe7,0x19 }, - { 0x4c,0x25,0xf5,0x02 }, { 0x41,0x2e,0xfb,0x0b }, - { 0x61,0x8c,0x9a,0xd7 }, { 0x6c,0x87,0x94,0xde }, - { 0x7b,0x9a,0x86,0xc5 }, { 0x76,0x91,0x88,0xcc }, - { 0x55,0xa0,0xa2,0xf3 }, { 0x58,0xab,0xac,0xfa }, - { 0x4f,0xb6,0xbe,0xe1 }, { 0x42,0xbd,0xb0,0xe8 }, - { 0x09,0xd4,0xea,0x9f }, { 0x04,0xdf,0xe4,0x96 }, - { 0x13,0xc2,0xf6,0x8d }, { 0x1e,0xc9,0xf8,0x84 }, - { 0x3d,0xf8,0xd2,0xbb }, { 0x30,0xf3,0xdc,0xb2 }, - { 0x27,0xee,0xce,0xa9 }, { 0x2a,0xe5,0xc0,0xa0 }, - { 0xb1,0x3c,0x7a,0x47 }, { 0xbc,0x37,0x74,0x4e }, - { 0xab,0x2a,0x66,0x55 }, { 0xa6,0x21,0x68,0x5c }, - { 0x85,0x10,0x42,0x63 }, { 0x88,0x1b,0x4c,0x6a }, - { 0x9f,0x06,0x5e,0x71 }, { 0x92,0x0d,0x50,0x78 }, - { 0xd9,0x64,0x0a,0x0f }, { 0xd4,0x6f,0x04,0x06 }, - { 0xc3,0x72,0x16,0x1d }, { 0xce,0x79,0x18,0x14 }, - { 0xed,0x48,0x32,0x2b }, { 0xe0,0x43,0x3c,0x22 }, - { 0xf7,0x5e,0x2e,0x39 }, { 0xfa,0x55,0x20,0x30 }, - { 0xb7,0x01,0xec,0x9a }, { 0xba,0x0a,0xe2,0x93 }, - { 0xad,0x17,0xf0,0x88 }, { 0xa0,0x1c,0xfe,0x81 }, - { 0x83,0x2d,0xd4,0xbe }, { 0x8e,0x26,0xda,0xb7 }, - { 0x99,0x3b,0xc8,0xac }, { 0x94,0x30,0xc6,0xa5 }, - { 0xdf,0x59,0x9c,0xd2 }, { 0xd2,0x52,0x92,0xdb }, - { 0xc5,0x4f,0x80,0xc0 }, { 0xc8,0x44,0x8e,0xc9 }, - { 0xeb,0x75,0xa4,0xf6 }, { 0xe6,0x7e,0xaa,0xff }, - { 0xf1,0x63,0xb8,0xe4 }, { 0xfc,0x68,0xb6,0xed }, - { 0x67,0xb1,0x0c,0x0a }, { 0x6a,0xba,0x02,0x03 }, - { 0x7d,0xa7,0x10,0x18 }, { 0x70,0xac,0x1e,0x11 }, - { 0x53,0x9d,0x34,0x2e }, { 0x5e,0x96,0x3a,0x27 }, - { 0x49,0x8b,0x28,0x3c }, { 0x44,0x80,0x26,0x35 }, - { 0x0f,0xe9,0x7c,0x42 }, { 0x02,0xe2,0x72,0x4b }, - { 0x15,0xff,0x60,0x50 }, { 0x18,0xf4,0x6e,0x59 }, - { 0x3b,0xc5,0x44,0x66 }, { 0x36,0xce,0x4a,0x6f }, - { 0x21,0xd3,0x58,0x74 }, { 0x2c,0xd8,0x56,0x7d }, - { 0x0c,0x7a,0x37,0xa1 }, { 0x01,0x71,0x39,0xa8 }, - { 0x16,0x6c,0x2b,0xb3 }, { 0x1b,0x67,0x25,0xba }, - { 0x38,0x56,0x0f,0x85 }, { 0x35,0x5d,0x01,0x8c }, - { 0x22,0x40,0x13,0x97 }, { 0x2f,0x4b,0x1d,0x9e }, - { 0x64,0x22,0x47,0xe9 }, { 0x69,0x29,0x49,0xe0 }, - { 0x7e,0x34,0x5b,0xfb }, { 0x73,0x3f,0x55,0xf2 }, - { 0x50,0x0e,0x7f,0xcd }, { 0x5d,0x05,0x71,0xc4 }, - { 0x4a,0x18,0x63,0xdf }, { 0x47,0x13,0x6d,0xd6 }, - { 0xdc,0xca,0xd7,0x31 }, { 0xd1,0xc1,0xd9,0x38 }, - { 0xc6,0xdc,0xcb,0x23 }, { 0xcb,0xd7,0xc5,0x2a }, - { 0xe8,0xe6,0xef,0x15 }, { 0xe5,0xed,0xe1,0x1c }, - { 0xf2,0xf0,0xf3,0x07 }, { 0xff,0xfb,0xfd,0x0e }, - { 0xb4,0x92,0xa7,0x79 }, { 0xb9,0x99,0xa9,0x70 }, - { 0xae,0x84,0xbb,0x6b }, { 0xa3,0x8f,0xb5,0x62 }, - { 0x80,0xbe,0x9f,0x5d }, { 0x8d,0xb5,0x91,0x54 }, - { 0x9a,0xa8,0x83,0x4f }, { 0x97,0xa3,0x8d,0x46 } - }; - -static const unsigned char U4[256][4] = - { - { 0x00,0x00,0x00,0x00 }, { 0x09,0x0d,0x0b,0x0e }, - { 0x12,0x1a,0x16,0x1c }, { 0x1b,0x17,0x1d,0x12 }, - { 0x24,0x34,0x2c,0x38 }, { 0x2d,0x39,0x27,0x36 }, - { 0x36,0x2e,0x3a,0x24 }, { 0x3f,0x23,0x31,0x2a }, - { 0x48,0x68,0x58,0x70 }, { 0x41,0x65,0x53,0x7e }, - { 0x5a,0x72,0x4e,0x6c }, { 0x53,0x7f,0x45,0x62 }, - { 0x6c,0x5c,0x74,0x48 }, { 0x65,0x51,0x7f,0x46 }, - { 0x7e,0x46,0x62,0x54 }, { 0x77,0x4b,0x69,0x5a }, - { 0x90,0xd0,0xb0,0xe0 }, { 0x99,0xdd,0xbb,0xee }, - { 0x82,0xca,0xa6,0xfc }, { 0x8b,0xc7,0xad,0xf2 }, - { 0xb4,0xe4,0x9c,0xd8 }, { 0xbd,0xe9,0x97,0xd6 }, - { 0xa6,0xfe,0x8a,0xc4 }, { 0xaf,0xf3,0x81,0xca }, - { 0xd8,0xb8,0xe8,0x90 }, { 0xd1,0xb5,0xe3,0x9e }, - { 0xca,0xa2,0xfe,0x8c }, { 0xc3,0xaf,0xf5,0x82 }, - { 0xfc,0x8c,0xc4,0xa8 }, { 0xf5,0x81,0xcf,0xa6 }, - { 0xee,0x96,0xd2,0xb4 }, { 0xe7,0x9b,0xd9,0xba }, - { 0x3b,0xbb,0x7b,0xdb }, { 0x32,0xb6,0x70,0xd5 }, - { 0x29,0xa1,0x6d,0xc7 }, { 0x20,0xac,0x66,0xc9 }, - { 0x1f,0x8f,0x57,0xe3 }, { 0x16,0x82,0x5c,0xed }, - { 0x0d,0x95,0x41,0xff }, { 0x04,0x98,0x4a,0xf1 }, - { 0x73,0xd3,0x23,0xab }, { 0x7a,0xde,0x28,0xa5 }, - { 0x61,0xc9,0x35,0xb7 }, { 0x68,0xc4,0x3e,0xb9 }, - { 0x57,0xe7,0x0f,0x93 }, { 0x5e,0xea,0x04,0x9d }, - { 0x45,0xfd,0x19,0x8f }, { 0x4c,0xf0,0x12,0x81 }, - { 0xab,0x6b,0xcb,0x3b }, { 0xa2,0x66,0xc0,0x35 }, - { 0xb9,0x71,0xdd,0x27 }, { 0xb0,0x7c,0xd6,0x29 }, - { 0x8f,0x5f,0xe7,0x03 }, { 0x86,0x52,0xec,0x0d }, - { 0x9d,0x45,0xf1,0x1f }, { 0x94,0x48,0xfa,0x11 }, - { 0xe3,0x03,0x93,0x4b }, { 0xea,0x0e,0x98,0x45 }, - { 0xf1,0x19,0x85,0x57 }, { 0xf8,0x14,0x8e,0x59 }, - { 0xc7,0x37,0xbf,0x73 }, { 0xce,0x3a,0xb4,0x7d }, - { 0xd5,0x2d,0xa9,0x6f }, { 0xdc,0x20,0xa2,0x61 }, - { 0x76,0x6d,0xf6,0xad }, { 0x7f,0x60,0xfd,0xa3 }, - { 0x64,0x77,0xe0,0xb1 }, { 0x6d,0x7a,0xeb,0xbf }, - { 0x52,0x59,0xda,0x95 }, { 0x5b,0x54,0xd1,0x9b }, - { 0x40,0x43,0xcc,0x89 }, { 0x49,0x4e,0xc7,0x87 }, - { 0x3e,0x05,0xae,0xdd }, { 0x37,0x08,0xa5,0xd3 }, - { 0x2c,0x1f,0xb8,0xc1 }, { 0x25,0x12,0xb3,0xcf }, - { 0x1a,0x31,0x82,0xe5 }, { 0x13,0x3c,0x89,0xeb }, - { 0x08,0x2b,0x94,0xf9 }, { 0x01,0x26,0x9f,0xf7 }, - { 0xe6,0xbd,0x46,0x4d }, { 0xef,0xb0,0x4d,0x43 }, - { 0xf4,0xa7,0x50,0x51 }, { 0xfd,0xaa,0x5b,0x5f }, - { 0xc2,0x89,0x6a,0x75 }, { 0xcb,0x84,0x61,0x7b }, - { 0xd0,0x93,0x7c,0x69 }, { 0xd9,0x9e,0x77,0x67 }, - { 0xae,0xd5,0x1e,0x3d }, { 0xa7,0xd8,0x15,0x33 }, - { 0xbc,0xcf,0x08,0x21 }, { 0xb5,0xc2,0x03,0x2f }, - { 0x8a,0xe1,0x32,0x05 }, { 0x83,0xec,0x39,0x0b }, - { 0x98,0xfb,0x24,0x19 }, { 0x91,0xf6,0x2f,0x17 }, - { 0x4d,0xd6,0x8d,0x76 }, { 0x44,0xdb,0x86,0x78 }, - { 0x5f,0xcc,0x9b,0x6a }, { 0x56,0xc1,0x90,0x64 }, - { 0x69,0xe2,0xa1,0x4e }, { 0x60,0xef,0xaa,0x40 }, - { 0x7b,0xf8,0xb7,0x52 }, { 0x72,0xf5,0xbc,0x5c }, - { 0x05,0xbe,0xd5,0x06 }, { 0x0c,0xb3,0xde,0x08 }, - { 0x17,0xa4,0xc3,0x1a }, { 0x1e,0xa9,0xc8,0x14 }, - { 0x21,0x8a,0xf9,0x3e }, { 0x28,0x87,0xf2,0x30 }, - { 0x33,0x90,0xef,0x22 }, { 0x3a,0x9d,0xe4,0x2c }, - { 0xdd,0x06,0x3d,0x96 }, { 0xd4,0x0b,0x36,0x98 }, - { 0xcf,0x1c,0x2b,0x8a }, { 0xc6,0x11,0x20,0x84 }, - { 0xf9,0x32,0x11,0xae }, { 0xf0,0x3f,0x1a,0xa0 }, - { 0xeb,0x28,0x07,0xb2 }, { 0xe2,0x25,0x0c,0xbc }, - { 0x95,0x6e,0x65,0xe6 }, { 0x9c,0x63,0x6e,0xe8 }, - { 0x87,0x74,0x73,0xfa }, { 0x8e,0x79,0x78,0xf4 }, - { 0xb1,0x5a,0x49,0xde }, { 0xb8,0x57,0x42,0xd0 }, - { 0xa3,0x40,0x5f,0xc2 }, { 0xaa,0x4d,0x54,0xcc }, - { 0xec,0xda,0xf7,0x41 }, { 0xe5,0xd7,0xfc,0x4f }, - { 0xfe,0xc0,0xe1,0x5d }, { 0xf7,0xcd,0xea,0x53 }, - { 0xc8,0xee,0xdb,0x79 }, { 0xc1,0xe3,0xd0,0x77 }, - { 0xda,0xf4,0xcd,0x65 }, { 0xd3,0xf9,0xc6,0x6b }, - { 0xa4,0xb2,0xaf,0x31 }, { 0xad,0xbf,0xa4,0x3f }, - { 0xb6,0xa8,0xb9,0x2d }, { 0xbf,0xa5,0xb2,0x23 }, - { 0x80,0x86,0x83,0x09 }, { 0x89,0x8b,0x88,0x07 }, - { 0x92,0x9c,0x95,0x15 }, { 0x9b,0x91,0x9e,0x1b }, - { 0x7c,0x0a,0x47,0xa1 }, { 0x75,0x07,0x4c,0xaf }, - { 0x6e,0x10,0x51,0xbd }, { 0x67,0x1d,0x5a,0xb3 }, - { 0x58,0x3e,0x6b,0x99 }, { 0x51,0x33,0x60,0x97 }, - { 0x4a,0x24,0x7d,0x85 }, { 0x43,0x29,0x76,0x8b }, - { 0x34,0x62,0x1f,0xd1 }, { 0x3d,0x6f,0x14,0xdf }, - { 0x26,0x78,0x09,0xcd }, { 0x2f,0x75,0x02,0xc3 }, - { 0x10,0x56,0x33,0xe9 }, { 0x19,0x5b,0x38,0xe7 }, - { 0x02,0x4c,0x25,0xf5 }, { 0x0b,0x41,0x2e,0xfb }, - { 0xd7,0x61,0x8c,0x9a }, { 0xde,0x6c,0x87,0x94 }, - { 0xc5,0x7b,0x9a,0x86 }, { 0xcc,0x76,0x91,0x88 }, - { 0xf3,0x55,0xa0,0xa2 }, { 0xfa,0x58,0xab,0xac }, - { 0xe1,0x4f,0xb6,0xbe }, { 0xe8,0x42,0xbd,0xb0 }, - { 0x9f,0x09,0xd4,0xea }, { 0x96,0x04,0xdf,0xe4 }, - { 0x8d,0x13,0xc2,0xf6 }, { 0x84,0x1e,0xc9,0xf8 }, - { 0xbb,0x3d,0xf8,0xd2 }, { 0xb2,0x30,0xf3,0xdc }, - { 0xa9,0x27,0xee,0xce }, { 0xa0,0x2a,0xe5,0xc0 }, - { 0x47,0xb1,0x3c,0x7a }, { 0x4e,0xbc,0x37,0x74 }, - { 0x55,0xab,0x2a,0x66 }, { 0x5c,0xa6,0x21,0x68 }, - { 0x63,0x85,0x10,0x42 }, { 0x6a,0x88,0x1b,0x4c }, - { 0x71,0x9f,0x06,0x5e }, { 0x78,0x92,0x0d,0x50 }, - { 0x0f,0xd9,0x64,0x0a }, { 0x06,0xd4,0x6f,0x04 }, - { 0x1d,0xc3,0x72,0x16 }, { 0x14,0xce,0x79,0x18 }, - { 0x2b,0xed,0x48,0x32 }, { 0x22,0xe0,0x43,0x3c }, - { 0x39,0xf7,0x5e,0x2e }, { 0x30,0xfa,0x55,0x20 }, - { 0x9a,0xb7,0x01,0xec }, { 0x93,0xba,0x0a,0xe2 }, - { 0x88,0xad,0x17,0xf0 }, { 0x81,0xa0,0x1c,0xfe }, - { 0xbe,0x83,0x2d,0xd4 }, { 0xb7,0x8e,0x26,0xda }, - { 0xac,0x99,0x3b,0xc8 }, { 0xa5,0x94,0x30,0xc6 }, - { 0xd2,0xdf,0x59,0x9c }, { 0xdb,0xd2,0x52,0x92 }, - { 0xc0,0xc5,0x4f,0x80 }, { 0xc9,0xc8,0x44,0x8e }, - { 0xf6,0xeb,0x75,0xa4 }, { 0xff,0xe6,0x7e,0xaa }, - { 0xe4,0xf1,0x63,0xb8 }, { 0xed,0xfc,0x68,0xb6 }, - { 0x0a,0x67,0xb1,0x0c }, { 0x03,0x6a,0xba,0x02 }, - { 0x18,0x7d,0xa7,0x10 }, { 0x11,0x70,0xac,0x1e }, - { 0x2e,0x53,0x9d,0x34 }, { 0x27,0x5e,0x96,0x3a }, - { 0x3c,0x49,0x8b,0x28 }, { 0x35,0x44,0x80,0x26 }, - { 0x42,0x0f,0xe9,0x7c }, { 0x4b,0x02,0xe2,0x72 }, - { 0x50,0x15,0xff,0x60 }, { 0x59,0x18,0xf4,0x6e }, - { 0x66,0x3b,0xc5,0x44 }, { 0x6f,0x36,0xce,0x4a }, - { 0x74,0x21,0xd3,0x58 }, { 0x7d,0x2c,0xd8,0x56 }, - { 0xa1,0x0c,0x7a,0x37 }, { 0xa8,0x01,0x71,0x39 }, - { 0xb3,0x16,0x6c,0x2b }, { 0xba,0x1b,0x67,0x25 }, - { 0x85,0x38,0x56,0x0f }, { 0x8c,0x35,0x5d,0x01 }, - { 0x97,0x22,0x40,0x13 }, { 0x9e,0x2f,0x4b,0x1d }, - { 0xe9,0x64,0x22,0x47 }, { 0xe0,0x69,0x29,0x49 }, - { 0xfb,0x7e,0x34,0x5b }, { 0xf2,0x73,0x3f,0x55 }, - { 0xcd,0x50,0x0e,0x7f }, { 0xc4,0x5d,0x05,0x71 }, - { 0xdf,0x4a,0x18,0x63 }, { 0xd6,0x47,0x13,0x6d }, - { 0x31,0xdc,0xca,0xd7 }, { 0x38,0xd1,0xc1,0xd9 }, - { 0x23,0xc6,0xdc,0xcb }, { 0x2a,0xcb,0xd7,0xc5 }, - { 0x15,0xe8,0xe6,0xef }, { 0x1c,0xe5,0xed,0xe1 }, - { 0x07,0xf2,0xf0,0xf3 }, { 0x0e,0xff,0xfb,0xfd }, - { 0x79,0xb4,0x92,0xa7 }, { 0x70,0xb9,0x99,0xa9 }, - { 0x6b,0xae,0x84,0xbb }, { 0x62,0xa3,0x8f,0xb5 }, - { 0x5d,0x80,0xbe,0x9f }, { 0x54,0x8d,0xb5,0x91 }, - { 0x4f,0x9a,0xa8,0x83 }, { 0x46,0x97,0xa3,0x8d } - }; +#define decT dec_tables.T +#define inv_sbox dec_tables.inv_sbox static const u32 rcon[30] = { diff --git a/cipher/rijndael.c b/cipher/rijndael.c index aa1681d..5b0fe1c 100644 --- a/cipher/rijndael.c +++ b/cipher/rijndael.c @@ -63,12 +63,14 @@ typedef u32 u32_a_t; extern unsigned int _gcry_aes_amd64_encrypt_block(const void *keysched_enc, unsigned char *out, const unsigned char *in, - int rounds); + 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); + int rounds, + const void *decT); #endif /*USE_AMD64_ASM*/ #ifdef USE_AESNI @@ -119,12 +121,14 @@ extern unsigned int _gcry_aes_padlock_decrypt (const RIJNDAEL_context *ctx, extern unsigned int _gcry_aes_arm_encrypt_block(const void *keysched_enc, unsigned char *out, const unsigned char *in, - int rounds); + 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); + int rounds, + const void *decT); #endif /*USE_ARM_ASM*/ static unsigned int do_encrypt (const RIJNDAEL_context *ctx, unsigned char *bx, @@ -145,6 +149,38 @@ static const char *selftest(void); +/* Prefetching for encryption/decryption tables. */ +static void prefetch_table(const volatile byte *tab, size_t len) +{ + size_t i; + + for (i = 0; i < len; i += 8 * 32) + { + (void)tab[i + 0 * 32]; + (void)tab[i + 1 * 32]; + (void)tab[i + 2 * 32]; + (void)tab[i + 3 * 32]; + (void)tab[i + 4 * 32]; + (void)tab[i + 5 * 32]; + (void)tab[i + 6 * 32]; + (void)tab[i + 7 * 32]; + } + + (void)tab[len - 1]; +} + +static void prefetch_enc(void) +{ + prefetch_table((const void *)encT, sizeof(encT)); +} + +static void prefetch_dec(void) +{ + prefetch_table((const void *)&dec_tables, sizeof(dec_tables)); +} + + + /* Perform the key setup. */ static gcry_err_code_t do_setkey (RIJNDAEL_context *ctx, const byte *key, const unsigned keylen) @@ -216,6 +252,8 @@ do_setkey (RIJNDAEL_context *ctx, const byte *key, const unsigned keylen) { ctx->encrypt_fn = _gcry_aes_aesni_encrypt; ctx->decrypt_fn = _gcry_aes_aesni_decrypt; + ctx->prefetch_enc_fn = NULL; + ctx->prefetch_dec_fn = NULL; ctx->use_aesni = 1; } #endif @@ -224,6 +262,8 @@ do_setkey (RIJNDAEL_context *ctx, const byte *key, const unsigned keylen) { ctx->encrypt_fn = _gcry_aes_padlock_encrypt; ctx->decrypt_fn = _gcry_aes_padlock_decrypt; + ctx->prefetch_enc_fn = NULL; + ctx->prefetch_dec_fn = NULL; ctx->use_padlock = 1; memcpy (ctx->padlockkey, key, keylen); } @@ -232,6 +272,8 @@ do_setkey (RIJNDAEL_context *ctx, const byte *key, const unsigned keylen) { ctx->encrypt_fn = do_encrypt; ctx->decrypt_fn = do_decrypt; + ctx->prefetch_enc_fn = prefetch_enc; + ctx->prefetch_dec_fn = prefetch_dec; } /* NB: We don't yet support Padlock hardware key generation. */ @@ -246,14 +288,18 @@ do_setkey (RIJNDAEL_context *ctx, const byte *key, const unsigned keylen) #endif else { + const byte *sbox = ((const byte *)encT) + 1; union { PROPERLY_ALIGNED_TYPE dummy; byte data[MAXKC][4]; - } k, tk; -#define k k.data -#define tk tk.data + } tkk[2]; +#define k tkk[0].data +#define tk tkk[1].data #define W (ctx->keyschenc) + + prefetch_enc(); + for (i = 0; i < keylen; i++) { k[i >> 2][i & 3] = key[i]; @@ -270,7 +316,7 @@ do_setkey (RIJNDAEL_context *ctx, const byte *key, const unsigned keylen) { for (; (j < KC) && (t < 4); j++, t++) { - *((u32_a_t*)W[r][t]) = *((u32_a_t*)tk[j]); + *((u32_a_t*)W[r][t]) = le_bswap32(*((u32_a_t*)tk[j])); } if (t == 4) { @@ -283,10 +329,10 @@ do_setkey (RIJNDAEL_context *ctx, const byte *key, const unsigned keylen) { /* While not enough round key material calculated calculate new values. */ - tk[0][0] ^= S[tk[KC-1][1]]; - tk[0][1] ^= S[tk[KC-1][2]]; - tk[0][2] ^= S[tk[KC-1][3]]; - tk[0][3] ^= S[tk[KC-1][0]]; + 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) @@ -302,10 +348,10 @@ do_setkey (RIJNDAEL_context *ctx, const byte *key, const unsigned keylen) { *((u32_a_t*)tk[j]) ^= *((u32_a_t*)tk[j-1]); } - tk[KC/2][0] ^= S[tk[KC/2 - 1][0]]; - tk[KC/2][1] ^= S[tk[KC/2 - 1][1]]; - tk[KC/2][2] ^= S[tk[KC/2 - 1][2]]; - tk[KC/2][3] ^= S[tk[KC/2 - 1][3]]; + 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++) { *((u32_a_t*)tk[j]) ^= *((u32_a_t*)tk[j-1]); @@ -317,7 +363,7 @@ do_setkey (RIJNDAEL_context *ctx, const byte *key, const unsigned keylen) { for (; (j < KC) && (t < 4); j++, t++) { - *((u32_a_t*)W[r][t]) = *((u32_a_t*)tk[j]); + *((u32_a_t*)W[r][t]) = le_bswap32(*((u32_a_t*)tk[j])); } if (t == 4) { @@ -329,8 +375,7 @@ do_setkey (RIJNDAEL_context *ctx, const byte *key, const unsigned keylen) #undef W #undef tk #undef k - wipememory(&tk, sizeof(tk)); - wipememory(&t, sizeof(t)); + wipememory(&tkk, sizeof(tkk)); } return 0; @@ -367,136 +412,190 @@ prepare_decryption( RIJNDAEL_context *ctx ) #endif /*USE_PADLOCK*/ else { - union - { - PROPERLY_ALIGNED_TYPE dummy; - byte *w; - } w; -#define w w.w + const byte *sbox = ((const byte *)encT) + 1; - for (r=0; r < MAXROUNDS+1; r++ ) - { - *((u32_a_t*)ctx->keyschdec[r][0]) = *((u32_a_t*)ctx->keyschenc[r][0]); - *((u32_a_t*)ctx->keyschdec[r][1]) = *((u32_a_t*)ctx->keyschenc[r][1]); - *((u32_a_t*)ctx->keyschdec[r][2]) = *((u32_a_t*)ctx->keyschenc[r][2]); - *((u32_a_t*)ctx->keyschdec[r][3]) = *((u32_a_t*)ctx->keyschenc[r][3]); - } -#define W (ctx->keyschdec) - for (r = 1; r < ctx->rounds; r++) - { - w = W[r][0]; - *((u32_a_t*)w) = *((u32_a_t*)U1[w[0]]) ^ *((u32_a_t*)U2[w[1]]) - ^ *((u32_a_t*)U3[w[2]]) ^ *((u32_a_t*)U4[w[3]]); + prefetch_enc(); + prefetch_dec(); - w = W[r][1]; - *((u32_a_t*)w) = *((u32_a_t*)U1[w[0]]) ^ *((u32_a_t*)U2[w[1]]) - ^ *((u32_a_t*)U3[w[2]]) ^ *((u32_a_t*)U4[w[3]]); + *((u32_a_t*)ctx->keyschdec[0][0]) = *((u32_a_t*)ctx->keyschenc[0][0]); + *((u32_a_t*)ctx->keyschdec[0][1]) = *((u32_a_t*)ctx->keyschenc[0][1]); + *((u32_a_t*)ctx->keyschdec[0][2]) = *((u32_a_t*)ctx->keyschenc[0][2]); + *((u32_a_t*)ctx->keyschdec[0][3]) = *((u32_a_t*)ctx->keyschenc[0][3]); - w = W[r][2]; - *((u32_a_t*)w) = *((u32_a_t*)U1[w[0]]) ^ *((u32_a_t*)U2[w[1]]) - ^ *((u32_a_t*)U3[w[2]]) ^ *((u32_a_t*)U4[w[3]]); - - w = W[r][3]; - *((u32_a_t*)w) = *((u32_a_t*)U1[w[0]]) ^ *((u32_a_t*)U2[w[1]]) - ^ *((u32_a_t*)U3[w[2]]) ^ *((u32_a_t*)U4[w[3]]); + for (r = 1; r < ctx->rounds; r++) + { + u32_a_t *wi = (u32_a_t*)((ctx->keyschenc)[r]); + u32_a_t *wo = (u32_a_t*)((ctx->keyschdec)[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); } -#undef W -#undef w - wipememory(&w, sizeof(w)); + + *((u32_a_t*)ctx->keyschdec[r][0]) = *((u32_a_t*)ctx->keyschenc[r][0]); + *((u32_a_t*)ctx->keyschdec[r][1]) = *((u32_a_t*)ctx->keyschenc[r][1]); + *((u32_a_t*)ctx->keyschdec[r][2]) = *((u32_a_t*)ctx->keyschenc[r][2]); + *((u32_a_t*)ctx->keyschdec[r][3]) = *((u32_a_t*)ctx->keyschenc[r][3]); } } -#if !defined(USE_AMD64_ASM) && !defined(USE_ARM_ASM) -/* Encrypt one block. A and B need to be aligned on a 4 byte - boundary. A and B may be the same. */ -static void -do_encrypt_aligned (const RIJNDAEL_context *ctx, - unsigned char *b, const unsigned char *a) +#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->keyschenc) + const byte *sbox = ((const byte *)encT) + 1; int rounds = ctx->rounds; int r; - union - { - u32 tempu32[4]; /* Force correct alignment. */ - byte temp[4][4]; - } u; - - *((u32_a_t*)u.temp[0]) = *((u32_a_t*)(a )) ^ *((u32_a_t*)rk[0][0]); - *((u32_a_t*)u.temp[1]) = *((u32_a_t*)(a+ 4)) ^ *((u32_a_t*)rk[0][1]); - *((u32_a_t*)u.temp[2]) = *((u32_a_t*)(a+ 8)) ^ *((u32_a_t*)rk[0][2]); - *((u32_a_t*)u.temp[3]) = *((u32_a_t*)(a+12)) ^ *((u32_a_t*)rk[0][3]); - *((u32_a_t*)(b )) = (*((u32_a_t*)T1[u.temp[0][0]]) - ^ *((u32_a_t*)T2[u.temp[1][1]]) - ^ *((u32_a_t*)T3[u.temp[2][2]]) - ^ *((u32_a_t*)T4[u.temp[3][3]])); - *((u32_a_t*)(b + 4)) = (*((u32_a_t*)T1[u.temp[1][0]]) - ^ *((u32_a_t*)T2[u.temp[2][1]]) - ^ *((u32_a_t*)T3[u.temp[3][2]]) - ^ *((u32_a_t*)T4[u.temp[0][3]])); - *((u32_a_t*)(b + 8)) = (*((u32_a_t*)T1[u.temp[2][0]]) - ^ *((u32_a_t*)T2[u.temp[3][1]]) - ^ *((u32_a_t*)T3[u.temp[0][2]]) - ^ *((u32_a_t*)T4[u.temp[1][3]])); - *((u32_a_t*)(b +12)) = (*((u32_a_t*)T1[u.temp[3][0]]) - ^ *((u32_a_t*)T2[u.temp[0][1]]) - ^ *((u32_a_t*)T3[u.temp[1][2]]) - ^ *((u32_a_t*)T4[u.temp[2][3]])); - - for (r = 1; r < rounds-1; 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] ^ *((u32_a_t*)rk[0][0]); + sa[1] = sb[1] ^ *((u32_a_t*)rk[0][1]); + sa[2] = sb[2] ^ *((u32_a_t*)rk[0][2]); + sa[3] = sb[3] ^ *((u32_a_t*)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] = *((u32_a_t*)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] = *((u32_a_t*)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] = *((u32_a_t*)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] = *((u32_a_t*)rk[1][3]) ^ sb[3]; + + for (r = 2; r < rounds; r++) { - *((u32_a_t*)u.temp[0]) = *((u32_a_t*)(b )) ^ *((u32_a_t*)rk[r][0]); - *((u32_a_t*)u.temp[1]) = *((u32_a_t*)(b+ 4)) ^ *((u32_a_t*)rk[r][1]); - *((u32_a_t*)u.temp[2]) = *((u32_a_t*)(b+ 8)) ^ *((u32_a_t*)rk[r][2]); - *((u32_a_t*)u.temp[3]) = *((u32_a_t*)(b+12)) ^ *((u32_a_t*)rk[r][3]); - - *((u32_a_t*)(b )) = (*((u32_a_t*)T1[u.temp[0][0]]) - ^ *((u32_a_t*)T2[u.temp[1][1]]) - ^ *((u32_a_t*)T3[u.temp[2][2]]) - ^ *((u32_a_t*)T4[u.temp[3][3]])); - *((u32_a_t*)(b + 4)) = (*((u32_a_t*)T1[u.temp[1][0]]) - ^ *((u32_a_t*)T2[u.temp[2][1]]) - ^ *((u32_a_t*)T3[u.temp[3][2]]) - ^ *((u32_a_t*)T4[u.temp[0][3]])); - *((u32_a_t*)(b + 8)) = (*((u32_a_t*)T1[u.temp[2][0]]) - ^ *((u32_a_t*)T2[u.temp[3][1]]) - ^ *((u32_a_t*)T3[u.temp[0][2]]) - ^ *((u32_a_t*)T4[u.temp[1][3]])); - *((u32_a_t*)(b +12)) = (*((u32_a_t*)T1[u.temp[3][0]]) - ^ *((u32_a_t*)T2[u.temp[0][1]]) - ^ *((u32_a_t*)T3[u.temp[1][2]]) - ^ *((u32_a_t*)T4[u.temp[2][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] = *((u32_a_t*)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] = *((u32_a_t*)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] = *((u32_a_t*)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] = *((u32_a_t*)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] = *((u32_a_t*)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] = *((u32_a_t*)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] = *((u32_a_t*)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] = *((u32_a_t*)rk[r][3]) ^ sb[3]; } /* Last round is special. */ - *((u32_a_t*)u.temp[0]) = *((u32_a_t*)(b )) ^ *((u32_a_t*)rk[rounds-1][0]); - *((u32_a_t*)u.temp[1]) = *((u32_a_t*)(b+ 4)) ^ *((u32_a_t*)rk[rounds-1][1]); - *((u32_a_t*)u.temp[2]) = *((u32_a_t*)(b+ 8)) ^ *((u32_a_t*)rk[rounds-1][2]); - *((u32_a_t*)u.temp[3]) = *((u32_a_t*)(b+12)) ^ *((u32_a_t*)rk[rounds-1][3]); - b[ 0] = T1[u.temp[0][0]][1]; - b[ 1] = T1[u.temp[1][1]][1]; - b[ 2] = T1[u.temp[2][2]][1]; - b[ 3] = T1[u.temp[3][3]][1]; - b[ 4] = T1[u.temp[1][0]][1]; - b[ 5] = T1[u.temp[2][1]][1]; - b[ 6] = T1[u.temp[3][2]][1]; - b[ 7] = T1[u.temp[0][3]][1]; - b[ 8] = T1[u.temp[2][0]][1]; - b[ 9] = T1[u.temp[3][1]][1]; - b[10] = T1[u.temp[0][2]][1]; - b[11] = T1[u.temp[1][3]][1]; - b[12] = T1[u.temp[3][0]][1]; - b[13] = T1[u.temp[0][1]][1]; - b[14] = T1[u.temp[1][2]][1]; - b[15] = T1[u.temp[2][3]][1]; - *((u32_a_t*)(b )) ^= *((u32_a_t*)rk[rounds][0]); - *((u32_a_t*)(b+ 4)) ^= *((u32_a_t*)rk[rounds][1]); - *((u32_a_t*)(b+ 8)) ^= *((u32_a_t*)rk[rounds][2]); - *((u32_a_t*)(b+12)) ^= *((u32_a_t*)rk[rounds][3]); + + sb[0] = (sbox[(byte)(sa[0] >> (0 * 8)) * 4]) << (0 * 8); + sb[3] = (sbox[(byte)(sa[0] >> (1 * 8)) * 4]) << (1 * 8); + sb[2] = (sbox[(byte)(sa[0] >> (2 * 8)) * 4]) << (2 * 8); + sb[1] = (sbox[(byte)(sa[0] >> (3 * 8)) * 4]) << (3 * 8); + sa[0] = *((u32_a_t*)rk[r][0]) ^ sb[0]; + + sb[1] ^= (sbox[(byte)(sa[1] >> (0 * 8)) * 4]) << (0 * 8); + sa[0] ^= (sbox[(byte)(sa[1] >> (1 * 8)) * 4]) << (1 * 8); + sb[3] ^= (sbox[(byte)(sa[1] >> (2 * 8)) * 4]) << (2 * 8); + sb[2] ^= (sbox[(byte)(sa[1] >> (3 * 8)) * 4]) << (3 * 8); + sa[1] = *((u32_a_t*)rk[r][1]) ^ sb[1]; + + sb[2] ^= (sbox[(byte)(sa[2] >> (0 * 8)) * 4]) << (0 * 8); + sa[1] ^= (sbox[(byte)(sa[2] >> (1 * 8)) * 4]) << (1 * 8); + sa[0] ^= (sbox[(byte)(sa[2] >> (2 * 8)) * 4]) << (2 * 8); + sb[3] ^= (sbox[(byte)(sa[2] >> (3 * 8)) * 4]) << (3 * 8); + sa[2] = *((u32_a_t*)rk[r][2]) ^ sb[2]; + + sb[3] ^= (sbox[(byte)(sa[3] >> (0 * 8)) * 4]) << (0 * 8); + sa[2] ^= (sbox[(byte)(sa[3] >> (1 * 8)) * 4]) << (1 * 8); + sa[1] ^= (sbox[(byte)(sa[3] >> (2 * 8)) * 4]) << (2 * 8); + sa[0] ^= (sbox[(byte)(sa[3] >> (3 * 8)) * 4]) << (3 * 8); + sa[3] = *((u32_a_t*)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_AMD64_ASM && !USE_ARM_ASM*/ +#endif /*!USE_ARM_ASM && !USE_AMD64_ASM*/ static unsigned int @@ -504,31 +603,13 @@ 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); + return _gcry_aes_amd64_encrypt_block(ctx->keyschenc, bx, ax, ctx->rounds, + encT); #elif defined(USE_ARM_ASM) - return _gcry_aes_arm_encrypt_block(ctx->keyschenc, bx, ax, ctx->rounds); + return _gcry_aes_arm_encrypt_block(ctx->keyschenc, bx, ax, ctx->rounds, encT); #else - /* BX and AX are not necessary correctly aligned. Thus we might - need to copy them here. We try to align to a 16 bytes. */ - if (((size_t)ax & 0x0f) || ((size_t)bx & 0x0f)) - { - union - { - u32 dummy[4]; - byte a[16] ATTR_ALIGNED_16; - } a; - - buf_cpy (a.a, ax, 16); - do_encrypt_aligned (ctx, a.a, a.a); - buf_cpy (bx, a.a, 16); - } - else - { - do_encrypt_aligned (ctx, bx, ax); - } - - return (56 + 2*sizeof(int)); -#endif /*!USE_AMD64_ASM && !USE_ARM_ASM*/ + return do_encrypt_fn (ctx, bx, ax); +#endif /* !USE_ARM_ASM && !USE_AMD64_ASM*/ } @@ -537,6 +618,9 @@ 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); } @@ -555,6 +639,9 @@ _gcry_aes_cfb_enc (void *context, unsigned char *iv, const unsigned char *inbuf = inbuf_arg; unsigned int burn_depth = 0; + if (ctx->prefetch_enc_fn) + ctx->prefetch_enc_fn(); + if (0) ; #ifdef USE_AESNI @@ -599,6 +686,9 @@ _gcry_aes_cbc_enc (void *context, unsigned char *iv, unsigned char *last_iv; unsigned int burn_depth = 0; + if (ctx->prefetch_enc_fn) + ctx->prefetch_enc_fn(); + if (0) ; #ifdef USE_AESNI @@ -651,6 +741,9 @@ _gcry_aes_ctr_enc (void *context, unsigned char *ctr, unsigned int burn_depth = 0; int i; + if (ctx->prefetch_enc_fn) + ctx->prefetch_enc_fn(); + if (0) ; #ifdef USE_AESNI @@ -691,98 +784,139 @@ _gcry_aes_ctr_enc (void *context, unsigned char *ctr, -#if !defined(USE_AMD64_ASM) && !defined(USE_ARM_ASM) -/* Decrypt one block. A and B need to be aligned on a 4 byte boundary - and the decryption must have been prepared. A and B may be the - same. */ -static void -do_decrypt_aligned (const RIJNDAEL_context *ctx, - unsigned char *b, const unsigned char *a) +#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->keyschdec) int rounds = ctx->rounds; int r; - union - { - u32 tempu32[4]; /* Force correct alignment. */ - byte temp[4][4]; - } u; - - - *((u32_a_t*)u.temp[0]) = *((u32_a_t*)(a )) ^ *((u32_a_t*)rk[rounds][0]); - *((u32_a_t*)u.temp[1]) = *((u32_a_t*)(a+ 4)) ^ *((u32_a_t*)rk[rounds][1]); - *((u32_a_t*)u.temp[2]) = *((u32_a_t*)(a+ 8)) ^ *((u32_a_t*)rk[rounds][2]); - *((u32_a_t*)u.temp[3]) = *((u32_a_t*)(a+12)) ^ *((u32_a_t*)rk[rounds][3]); - - *((u32_a_t*)(b )) = (*((u32_a_t*)T5[u.temp[0][0]]) - ^ *((u32_a_t*)T6[u.temp[3][1]]) - ^ *((u32_a_t*)T7[u.temp[2][2]]) - ^ *((u32_a_t*)T8[u.temp[1][3]])); - *((u32_a_t*)(b+ 4)) = (*((u32_a_t*)T5[u.temp[1][0]]) - ^ *((u32_a_t*)T6[u.temp[0][1]]) - ^ *((u32_a_t*)T7[u.temp[3][2]]) - ^ *((u32_a_t*)T8[u.temp[2][3]])); - *((u32_a_t*)(b+ 8)) = (*((u32_a_t*)T5[u.temp[2][0]]) - ^ *((u32_a_t*)T6[u.temp[1][1]]) - ^ *((u32_a_t*)T7[u.temp[0][2]]) - ^ *((u32_a_t*)T8[u.temp[3][3]])); - *((u32_a_t*)(b+12)) = (*((u32_a_t*)T5[u.temp[3][0]]) - ^ *((u32_a_t*)T6[u.temp[2][1]]) - ^ *((u32_a_t*)T7[u.temp[1][2]]) - ^ *((u32_a_t*)T8[u.temp[0][3]])); - - for (r = rounds-1; r > 1; 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] ^ *((u32_a_t*)rk[rounds][0]); + sa[1] = sb[1] ^ *((u32_a_t*)rk[rounds][1]); + sa[2] = sb[2] ^ *((u32_a_t*)rk[rounds][2]); + sa[3] = sb[3] ^ *((u32_a_t*)rk[rounds][3]); + + for (r = rounds - 1; r > 1; r--) { - *((u32_a_t*)u.temp[0]) = *((u32_a_t*)(b )) ^ *((u32_a_t*)rk[r][0]); - *((u32_a_t*)u.temp[1]) = *((u32_a_t*)(b+ 4)) ^ *((u32_a_t*)rk[r][1]); - *((u32_a_t*)u.temp[2]) = *((u32_a_t*)(b+ 8)) ^ *((u32_a_t*)rk[r][2]); - *((u32_a_t*)u.temp[3]) = *((u32_a_t*)(b+12)) ^ *((u32_a_t*)rk[r][3]); - *((u32_a_t*)(b )) = (*((u32_a_t*)T5[u.temp[0][0]]) - ^ *((u32_a_t*)T6[u.temp[3][1]]) - ^ *((u32_a_t*)T7[u.temp[2][2]]) - ^ *((u32_a_t*)T8[u.temp[1][3]])); - *((u32_a_t*)(b+ 4)) = (*((u32_a_t*)T5[u.temp[1][0]]) - ^ *((u32_a_t*)T6[u.temp[0][1]]) - ^ *((u32_a_t*)T7[u.temp[3][2]]) - ^ *((u32_a_t*)T8[u.temp[2][3]])); - *((u32_a_t*)(b+ 8)) = (*((u32_a_t*)T5[u.temp[2][0]]) - ^ *((u32_a_t*)T6[u.temp[1][1]]) - ^ *((u32_a_t*)T7[u.temp[0][2]]) - ^ *((u32_a_t*)T8[u.temp[3][3]])); - *((u32_a_t*)(b+12)) = (*((u32_a_t*)T5[u.temp[3][0]]) - ^ *((u32_a_t*)T6[u.temp[2][1]]) - ^ *((u32_a_t*)T7[u.temp[1][2]]) - ^ *((u32_a_t*)T8[u.temp[0][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] = *((u32_a_t*)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] = *((u32_a_t*)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] = *((u32_a_t*)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] = *((u32_a_t*)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] = *((u32_a_t*)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] = *((u32_a_t*)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] = *((u32_a_t*)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] = *((u32_a_t*)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] = *((u32_a_t*)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] = *((u32_a_t*)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] = *((u32_a_t*)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] = *((u32_a_t*)rk[1][3]) ^ sb[3]; + /* Last round is special. */ - *((u32_a_t*)u.temp[0]) = *((u32_a_t*)(b )) ^ *((u32_a_t*)rk[1][0]); - *((u32_a_t*)u.temp[1]) = *((u32_a_t*)(b+ 4)) ^ *((u32_a_t*)rk[1][1]); - *((u32_a_t*)u.temp[2]) = *((u32_a_t*)(b+ 8)) ^ *((u32_a_t*)rk[1][2]); - *((u32_a_t*)u.temp[3]) = *((u32_a_t*)(b+12)) ^ *((u32_a_t*)rk[1][3]); - b[ 0] = S5[u.temp[0][0]]; - b[ 1] = S5[u.temp[3][1]]; - b[ 2] = S5[u.temp[2][2]]; - b[ 3] = S5[u.temp[1][3]]; - b[ 4] = S5[u.temp[1][0]]; - b[ 5] = S5[u.temp[0][1]]; - b[ 6] = S5[u.temp[3][2]]; - b[ 7] = S5[u.temp[2][3]]; - b[ 8] = S5[u.temp[2][0]]; - b[ 9] = S5[u.temp[1][1]]; - b[10] = S5[u.temp[0][2]]; - b[11] = S5[u.temp[3][3]]; - b[12] = S5[u.temp[3][0]]; - b[13] = S5[u.temp[2][1]]; - b[14] = S5[u.temp[1][2]]; - b[15] = S5[u.temp[0][3]]; - *((u32_a_t*)(b )) ^= *((u32_a_t*)rk[0][0]); - *((u32_a_t*)(b+ 4)) ^= *((u32_a_t*)rk[0][1]); - *((u32_a_t*)(b+ 8)) ^= *((u32_a_t*)rk[0][2]); - *((u32_a_t*)(b+12)) ^= *((u32_a_t*)rk[0][3]); + sb[0] = inv_sbox[(byte)(sa[0] >> (0 * 8))] << (0 * 8); + sb[1] = inv_sbox[(byte)(sa[0] >> (1 * 8))] << (1 * 8); + sb[2] = inv_sbox[(byte)(sa[0] >> (2 * 8))] << (2 * 8); + sb[3] = inv_sbox[(byte)(sa[0] >> (3 * 8))] << (3 * 8); + sa[0] = sb[0] ^ *((u32_a_t*)rk[0][0]); + + sb[1] ^= inv_sbox[(byte)(sa[1] >> (0 * 8))] << (0 * 8); + sb[2] ^= inv_sbox[(byte)(sa[1] >> (1 * 8))] << (1 * 8); + sb[3] ^= inv_sbox[(byte)(sa[1] >> (2 * 8))] << (2 * 8); + sa[0] ^= inv_sbox[(byte)(sa[1] >> (3 * 8))] << (3 * 8); + sa[1] = sb[1] ^ *((u32_a_t*)rk[0][1]); + + sb[2] ^= inv_sbox[(byte)(sa[2] >> (0 * 8))] << (0 * 8); + sb[3] ^= inv_sbox[(byte)(sa[2] >> (1 * 8))] << (1 * 8); + sa[0] ^= inv_sbox[(byte)(sa[2] >> (2 * 8))] << (2 * 8); + sa[1] ^= inv_sbox[(byte)(sa[2] >> (3 * 8))] << (3 * 8); + sa[2] = sb[2] ^ *((u32_a_t*)rk[0][2]); + + sb[3] ^= inv_sbox[(byte)(sa[3] >> (0 * 8))] << (0 * 8); + sa[0] ^= inv_sbox[(byte)(sa[3] >> (1 * 8))] << (1 * 8); + sa[1] ^= inv_sbox[(byte)(sa[3] >> (2 * 8))] << (2 * 8); + sa[2] ^= inv_sbox[(byte)(sa[3] >> (3 * 8))] << (3 * 8); + sa[3] = sb[3] ^ *((u32_a_t*)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_AMD64_ASM && !USE_ARM_ASM*/ +#endif /*!USE_ARM_ASM && !USE_AMD64_ASM*/ /* Decrypt one block. AX and BX may be the same. */ @@ -791,31 +925,14 @@ 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); + return _gcry_aes_amd64_decrypt_block(ctx->keyschdec, bx, ax, ctx->rounds, + &dec_tables); #elif defined(USE_ARM_ASM) - return _gcry_aes_arm_decrypt_block(ctx->keyschdec, bx, ax, ctx->rounds); + return _gcry_aes_arm_decrypt_block(ctx->keyschdec, bx, ax, ctx->rounds, + &dec_tables); #else - /* BX and AX are not necessary correctly aligned. Thus we might - need to copy them here. We try to align to a 16 bytes. */ - if (((size_t)ax & 0x0f) || ((size_t)bx & 0x0f)) - { - union - { - u32 dummy[4]; - byte a[16] ATTR_ALIGNED_16; - } a; - - buf_cpy (a.a, ax, 16); - do_decrypt_aligned (ctx, a.a, a.a); - buf_cpy (bx, a.a, 16); - } - else - { - do_decrypt_aligned (ctx, bx, ax); - } - - return (56+2*sizeof(int)); -#endif /*!USE_AMD64_ASM && !USE_ARM_ASM*/ + return do_decrypt_fn (ctx, bx, ax); +#endif /*!USE_ARM_ASM && !USE_AMD64_ASM*/ } @@ -837,6 +954,9 @@ rijndael_decrypt (void *context, byte *b, const byte *a) check_decryption_preparation (ctx); + if (ctx->prefetch_dec_fn) + ctx->prefetch_dec_fn(); + return ctx->decrypt_fn (ctx, b, a); } @@ -855,6 +975,9 @@ _gcry_aes_cfb_dec (void *context, unsigned char *iv, const unsigned char *inbuf = inbuf_arg; unsigned int burn_depth = 0; + if (ctx->prefetch_enc_fn) + ctx->prefetch_enc_fn(); + if (0) ; #ifdef USE_AESNI @@ -898,6 +1021,9 @@ _gcry_aes_cbc_dec (void *context, unsigned char *iv, check_decryption_preparation (ctx); + if (ctx->prefetch_dec_fn) + ctx->prefetch_dec_fn(); + if (0) ; #ifdef USE_AESNI @@ -932,7 +1058,6 @@ _gcry_aes_cbc_dec (void *context, unsigned char *iv, } - /* Run the self-tests for AES 128. Returns NULL on success. */ static const char* From wk at gnupg.org Sat Dec 20 18:58:28 2014 From: wk at gnupg.org (Werner Koch) Date: Sat, 20 Dec 2014 18:58:28 +0100 Subject: hex conversion In-Reply-To: <5492FB7A.2030704@campus.tu-berlin.de> (Max's message of "Thu, 18 Dec 2014 17:06:18 +0100") References: <5492FB7A.2030704@campus.tu-berlin.de> Message-ID: <877fxmw6d7.fsf@vigenere.g10code.de> On Thu, 18 Dec 2014 17:06, maxim.suraev at campus.tu-berlin.de said: > Am I missing something obvious or every user of libgcrypt writes its > own hex2bin() and bin2hex() functions? If you need an MPI, you can do that with gcry_error_t err; gcry_mpi_t n; char string[] = "abcdef010203040506070809"; err = gcry_mpi_scan (&n, GCRYMPI_FMT_HEX, string, 0, 0); if (err) print_error (); gcry_mpi_print and gcry_mpi_aprint can be used to print in hex format. S-expressions also have an hex format "(#abcdef010203040506070809)" and the s-expressions scanning fucntions support that. For everything elese you need to do it of your own (look at gnupg/common/convert.c). Shalom-Salam, Werner -- Die Gedanken sind frei. Ausnahmen regelt ein Bundesgesetz. From maxim.suraev at campus.tu-berlin.de Sun Dec 21 11:43:01 2014 From: maxim.suraev at campus.tu-berlin.de (Max) Date: Sun, 21 Dec 2014 11:43:01 +0100 Subject: hex conversion In-Reply-To: <877fxmw6d7.fsf@vigenere.g10code.de> References: <5492FB7A.2030704@campus.tu-berlin.de> <877fxmw6d7.fsf@vigenere.g10code.de> Message-ID: <5496A435.5090400@campus.tu-berlin.de> 20.12.2014 18:58, Werner Koch ?????: > If you need an MPI, you can do that with > > gcry_error_t err; > gcry_mpi_t n; > char string[] = "abcdef010203040506070809"; > > err = gcry_mpi_scan (&n, GCRYMPI_FMT_HEX, string, 0, 0); > if (err) > print_error (); > > gcry_mpi_print and gcry_mpi_aprint can be used to print in hex format. > > S-expressions also have an hex format "(#abcdef010203040506070809)" and > the s-expressions scanning fucntions support that. For everything elese > you need to do it of your own (look at gnupg/common/convert.c). > > Thank you for explanation. Although just duplicating code feels wrong - is there some library I could link against? cheers, Max. From jussi.kivilinna at iki.fi Sun Dec 21 16:38:01 2014 From: jussi.kivilinna at iki.fi (Jussi Kivilinna) Date: Sun, 21 Dec 2014 17:38:01 +0200 Subject: [PATCH 1/2] chacha20: allow setting counter for stream random access Message-ID: <20141221153801.16944.98683.stgit@localhost6.localdomain6> * cipher/chacha20.c (CHACHA20_CTR_SIZE): New. (chacha20_ivsetup): Add setup for full counter. (chacha20_setiv): Allow ivlen == CHACHA20_CTR_SIZE. -- Signed-off-by: Jussi Kivilinna --- cipher/chacha20.c | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/cipher/chacha20.c b/cipher/chacha20.c index c1847aa..2eaeffd 100644 --- a/cipher/chacha20.c +++ b/cipher/chacha20.c @@ -45,6 +45,7 @@ #define CHACHA20_BLOCK_SIZE 64 /* Bytes. */ #define CHACHA20_MIN_IV_SIZE 8 /* Bytes. */ #define CHACHA20_MAX_IV_SIZE 12 /* Bytes. */ +#define CHACHA20_CTR_SIZE 16 /* Bytes. */ #define CHACHA20_INPUT_LENGTH (CHACHA20_BLOCK_SIZE / 4) /* USE_SSE2 indicates whether to compile with Intel SSE2 code. */ @@ -312,22 +313,30 @@ chacha20_keysetup (CHACHA20_context_t * ctx, const byte * key, static void chacha20_ivsetup (CHACHA20_context_t * ctx, const byte * iv, size_t ivlen) { - ctx->input[12] = 0; - - if (ivlen == CHACHA20_MAX_IV_SIZE) + if (ivlen == CHACHA20_CTR_SIZE) + { + ctx->input[12] = buf_get_le32 (iv + 0); + ctx->input[13] = buf_get_le32 (iv + 4); + ctx->input[14] = buf_get_le32 (iv + 8); + ctx->input[15] = buf_get_le32 (iv + 12); + } + else if (ivlen == CHACHA20_MAX_IV_SIZE) { + ctx->input[12] = 0; ctx->input[13] = buf_get_le32 (iv + 0); ctx->input[14] = buf_get_le32 (iv + 4); ctx->input[15] = buf_get_le32 (iv + 8); } else if (ivlen == CHACHA20_MIN_IV_SIZE) { + ctx->input[12] = 0; ctx->input[13] = 0; ctx->input[14] = buf_get_le32 (iv + 0); ctx->input[15] = buf_get_le32 (iv + 4); } else { + ctx->input[12] = 0; ctx->input[13] = 0; ctx->input[14] = 0; ctx->input[15] = 0; @@ -402,10 +411,12 @@ chacha20_setiv (void *context, const byte * iv, size_t ivlen) CHACHA20_context_t *ctx = (CHACHA20_context_t *) context; /* draft-nir-cfrg-chacha20-poly1305-02 defines 96-bit and 64-bit nonce. */ - if (iv && ivlen != CHACHA20_MAX_IV_SIZE && ivlen != CHACHA20_MIN_IV_SIZE) + if (iv && ivlen != CHACHA20_MAX_IV_SIZE && ivlen != CHACHA20_MIN_IV_SIZE + && ivlen != CHACHA20_CTR_SIZE) log_info ("WARNING: chacha20_setiv: bad ivlen=%u\n", (u32) ivlen); - if (iv && (ivlen == CHACHA20_MAX_IV_SIZE || ivlen == CHACHA20_MIN_IV_SIZE)) + if (iv && (ivlen == CHACHA20_MAX_IV_SIZE || ivlen == CHACHA20_MIN_IV_SIZE + || ivlen == CHACHA20_CTR_SIZE)) chacha20_ivsetup (ctx, iv, ivlen); else chacha20_ivsetup (ctx, NULL, 0); From jussi.kivilinna at iki.fi Sun Dec 21 16:38:06 2014 From: jussi.kivilinna at iki.fi (Jussi Kivilinna) Date: Sun, 21 Dec 2014 17:38:06 +0200 Subject: [PATCH 2/2] Poly1305-AEAD: updated implementation to match draft-irtf-cfrg-chacha20-poly1305-03 In-Reply-To: <20141221153801.16944.98683.stgit@localhost6.localdomain6> References: <20141221153801.16944.98683.stgit@localhost6.localdomain6> Message-ID: <20141221153806.16944.34955.stgit@localhost6.localdomain6> * cipher/cipher-internal.h (gcry_cipher_handle): Use separate byte counters for AAD and data in Poly1305. * cipher/cipher-poly1305.c (poly1305_fill_bytecount): Remove. (poly1305_fill_bytecounts, poly1305_do_padding): New. (poly1305_aad_finish): Fill padding to Poly1305 and do not fill AAD length. (_gcry_cipher_poly1305_authenticate, _gcry_cipher_poly1305_encrypt) (_gcry_cipher_poly1305_decrypt): Update AAD and data length separately. (_gcry_cipher_poly1305_tag): Fill padding and bytecounts to Poly1305. (_gcry_cipher_poly1305_setkey, _gcry_cipher_poly1305_setiv): Reset AAD and data byte counts; only allow 96-bit IV. * cipher/cipher.c (_gcry_cipher_open_internal): Limit Poly1305-AEAD to ChaCha20 cipher. * tests/basic.c (_check_poly1305_cipher): Update test-vectors. (check_ciphers): Limit Poly1305-AEAD checks to ChaCha20. * tests/bench-slope.c (cipher_bench_one): Ditto. -- Latest Internet-Draft version for "ChaCha20 and Poly1305 for IETF protocols" has added additional padding to Poly1305-AEAD and limited support IV size to 96-bits: https://www.ietf.org/rfcdiff?url1=draft-nir-cfrg-chacha20-poly1305-03&difftype=--html&submit=Go!&url2=draft-irtf-cfrg-chacha20-poly1305-03 Patch makes Poly1305-AEAD implementation to match the changes and limits Poly1305-AEAD to ChaCha20 only. Signed-off-by: Jussi Kivilinna --- cipher/cipher-internal.h | 7 +++-- cipher/cipher-poly1305.c | 70 +++++++++++++++++++++++++++++++++------------- cipher/cipher.c | 4 +-- tests/basic.c | 70 +++++++++++++++++++++++++++++++++------------- tests/bench-slope.c | 6 +--- 5 files changed, 108 insertions(+), 49 deletions(-) diff --git a/cipher/cipher-internal.h b/cipher/cipher-internal.h index fef0ecb..650d813 100644 --- a/cipher/cipher-internal.h +++ b/cipher/cipher-internal.h @@ -163,8 +163,11 @@ struct gcry_cipher_handle /* Mode specific storage for Poly1305 mode. */ struct { - /* byte counter for AAD and data. */ - u32 bytecount[2]; + /* 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; diff --git a/cipher/cipher-poly1305.c b/cipher/cipher-poly1305.c index a22ffa3..f283333 100644 --- a/cipher/cipher-poly1305.c +++ b/cipher/cipher-poly1305.c @@ -53,12 +53,14 @@ poly1305_bytecounter_add (u32 ctr[2], size_t add) static void -poly1305_fill_bytecount (gcry_cipher_hd_t c) +poly1305_fill_bytecounts (gcry_cipher_hd_t c) { - u32 lenbuf[2]; + u32 lenbuf[4]; - lenbuf[0] = le_bswap32(c->u_mode.poly1305.bytecount[0]); - lenbuf[1] = le_bswap32(c->u_mode.poly1305.bytecount[1]); + lenbuf[0] = le_bswap32(c->u_mode.poly1305.aadcount[0]); + lenbuf[1] = le_bswap32(c->u_mode.poly1305.aadcount[1]); + lenbuf[2] = le_bswap32(c->u_mode.poly1305.datacount[0]); + lenbuf[3] = le_bswap32(c->u_mode.poly1305.datacount[1]); _gcry_poly1305_update (&c->u_mode.poly1305.ctx, (byte*)lenbuf, sizeof(lenbuf)); @@ -67,15 +69,33 @@ poly1305_fill_bytecount (gcry_cipher_hd_t c) static void +poly1305_do_padding (gcry_cipher_hd_t c, u32 ctr[2]) +{ + static const byte zero_padding_buf[15] = {}; + u32 padding_count; + + /* Padding to 16 byte boundary. */ + if (ctr[0] % 16 > 0) + { + padding_count = 16 - ctr[0] % 16; + + _gcry_poly1305_update (&c->u_mode.poly1305.ctx, zero_padding_buf, + padding_count); + } +} + + +static void poly1305_aad_finish (gcry_cipher_hd_t c) { - /* Start of encryption marks end of AAD stream. */ - poly1305_fill_bytecount(c); + /* After AAD, feed padding bytes so we get 16 byte alignment. */ + poly1305_do_padding (c, c->u_mode.poly1305.aadcount); + /* Start of encryption marks end of AAD stream. */ c->u_mode.poly1305.aad_finalized = 1; - c->u_mode.poly1305.bytecount[0] = 0; - c->u_mode.poly1305.bytecount[1] = 0; + c->u_mode.poly1305.datacount[0] = 0; + c->u_mode.poly1305.datacount[1] = 0; } @@ -102,7 +122,7 @@ _gcry_cipher_poly1305_authenticate (gcry_cipher_hd_t c, if (!c->marks.iv) poly1305_set_zeroiv(c); - if (poly1305_bytecounter_add(c->u_mode.poly1305.bytecount, aadbuflen)) + if (poly1305_bytecounter_add(c->u_mode.poly1305.aadcount, aadbuflen)) { c->u_mode.poly1305.bytecount_over_limits = 1; return GPG_ERR_INV_LENGTH; @@ -138,7 +158,7 @@ _gcry_cipher_poly1305_encrypt (gcry_cipher_hd_t c, if (!c->u_mode.poly1305.aad_finalized) poly1305_aad_finish(c); - if (poly1305_bytecounter_add(c->u_mode.poly1305.bytecount, inbuflen)) + if (poly1305_bytecounter_add(c->u_mode.poly1305.datacount, inbuflen)) { c->u_mode.poly1305.bytecount_over_limits = 1; return GPG_ERR_INV_LENGTH; @@ -176,7 +196,7 @@ _gcry_cipher_poly1305_decrypt (gcry_cipher_hd_t c, if (!c->u_mode.poly1305.aad_finalized) poly1305_aad_finish(c); - if (poly1305_bytecounter_add(c->u_mode.poly1305.bytecount, inbuflen)) + if (poly1305_bytecounter_add(c->u_mode.poly1305.datacount, inbuflen)) { c->u_mode.poly1305.bytecount_over_limits = 1; return GPG_ERR_INV_LENGTH; @@ -212,8 +232,11 @@ _gcry_cipher_poly1305_tag (gcry_cipher_hd_t c, if (!c->marks.tag) { - /* Write data-length to poly1305. */ - poly1305_fill_bytecount(c); + /* After data, feed padding bytes so we get 16 byte alignment. */ + poly1305_do_padding (c, c->u_mode.poly1305.datacount); + + /* Write byte counts to poly1305. */ + poly1305_fill_bytecounts(c); _gcry_poly1305_finish(&c->u_mode.poly1305.ctx, c->u_iv.iv); @@ -247,8 +270,11 @@ _gcry_cipher_poly1305_check_tag (gcry_cipher_hd_t c, const unsigned char *intag, void _gcry_cipher_poly1305_setkey (gcry_cipher_hd_t c) { - c->u_mode.poly1305.bytecount[0] = 0; - c->u_mode.poly1305.bytecount[1] = 0; + c->u_mode.poly1305.aadcount[0] = 0; + c->u_mode.poly1305.aadcount[1] = 0; + + c->u_mode.poly1305.datacount[0] = 0; + c->u_mode.poly1305.datacount[1] = 0; c->u_mode.poly1305.bytecount_over_limits = 0; c->u_mode.poly1305.aad_finalized = 0; @@ -260,16 +286,20 @@ _gcry_cipher_poly1305_setkey (gcry_cipher_hd_t c) gcry_err_code_t _gcry_cipher_poly1305_setiv (gcry_cipher_hd_t c, const byte *iv, size_t ivlen) { - byte tmpbuf[64]; /* size of ChaCha20/Salsa20 block */ + byte tmpbuf[64]; /* size of ChaCha20 block */ gcry_err_code_t err; - if (!iv && ivlen > 0) + /* IV must be 96-bits */ + if (!iv && ivlen != (96 / 8)) return GPG_ERR_INV_ARG; memset(&c->u_mode.poly1305.ctx, 0, sizeof(c->u_mode.poly1305.ctx)); - c->u_mode.poly1305.bytecount[0] = 0; - c->u_mode.poly1305.bytecount[1] = 0; + c->u_mode.poly1305.aadcount[0] = 0; + c->u_mode.poly1305.aadcount[1] = 0; + + c->u_mode.poly1305.datacount[0] = 0; + c->u_mode.poly1305.datacount[1] = 0; c->u_mode.poly1305.bytecount_over_limits = 0; c->u_mode.poly1305.aad_finalized = 0; @@ -279,7 +309,7 @@ _gcry_cipher_poly1305_setiv (gcry_cipher_hd_t c, const byte *iv, size_t ivlen) /* Set up IV for stream cipher. */ c->spec->setiv (&c->context.c, iv, ivlen); - /* Get the first block from ChaCha20/Salsa20. */ + /* Get the first block from ChaCha20. */ memset(tmpbuf, 0, sizeof(tmpbuf)); c->spec->stencrypt(&c->context.c, tmpbuf, tmpbuf, sizeof(tmpbuf)); diff --git a/cipher/cipher.c b/cipher/cipher.c index 5c44c0d..78cad21 100644 --- a/cipher/cipher.c +++ b/cipher/cipher.c @@ -421,9 +421,7 @@ _gcry_cipher_open_internal (gcry_cipher_hd_t *handle, case GCRY_CIPHER_MODE_POLY1305: if (!spec->stencrypt || !spec->stdecrypt || !spec->setiv) err = GPG_ERR_INV_CIPHER_MODE; - else if (spec->algo != GCRY_CIPHER_SALSA20 && - spec->algo != GCRY_CIPHER_SALSA20R12 && - spec->algo != GCRY_CIPHER_CHACHA20) + else if (spec->algo != GCRY_CIPHER_CHACHA20) err = GPG_ERR_INV_CIPHER_MODE; break; diff --git a/tests/basic.c b/tests/basic.c index e406db4..efafa68 100644 --- a/tests/basic.c +++ b/tests/basic.c @@ -1625,27 +1625,59 @@ _check_poly1305_cipher (unsigned int step) struct tv { int algo; - char key[MAX_DATA_LEN]; - char iv[MAX_DATA_LEN]; + const char *key; + const char *iv; int ivlen; - unsigned char aad[MAX_DATA_LEN]; + const char *aad; int aadlen; - unsigned char plaintext[MAX_DATA_LEN]; + const char *plaintext; int inlen; - char out[MAX_DATA_LEN]; - char tag[MAX_DATA_LEN]; + const char *out; + const char *tag; } tv[] = { - /* draft-agl-tls-chacha20poly1305-04 */ + /* draft-nir-cfrg-chacha20-poly1305-04 */ { GCRY_CIPHER_CHACHA20, - "\x42\x90\xbc\xb1\x54\x17\x35\x31\xf3\x14\xaf\x57\xf3\xbe\x3b\x50" - "\x06\xda\x37\x1e\xce\x27\x2a\xfa\x1b\x5d\xbd\xd1\x10\x0a\x10\x07", - "\xcd\x7c\xf6\x7b\xe3\x9c\x79\x4a", 8, - "\x87\xe2\x29\xd4\x50\x08\x45\xa0\x79\xc0", 10, - "\x86\xd0\x99\x74\x84\x0b\xde\xd2\xa5\xca", 10, - "\xe3\xe4\x46\xf7\xed\xe9\xa1\x9b\x62\xa4", - "\x67\x7d\xab\xf4\xe3\xd2\x4b\x87\x6b\xb2\x84\x75\x38\x96\xe1\xd6" }, - /* draft-nir-cfrg-chacha20-poly1305-03 */ + "\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-nir-cfrg-chacha20-poly1305-04 */ { 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", @@ -1661,11 +1693,11 @@ _check_poly1305_cipher (unsigned int step) "\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", - "\x18\xfb\x11\xa5\x03\x1a\xd1\x3a\x7e\x3b\x03\xd4\x6e\xe3\xa6\xa7" } + "\x1a\xe1\x0b\x59\x4f\x09\xe2\x6a\x7e\x90\x2e\xcb\xd0\x60\x06\x91" }, }; gcry_cipher_hd_t hde, hdd; - unsigned char out[MAX_DATA_LEN]; + unsigned char out[1024]; unsigned char tag[16]; int i, keylen; gcry_error_t err = 0; @@ -4333,9 +4365,7 @@ check_ciphers (void) gcry_cipher_algo_name (algos2[i])); check_one_cipher (algos2[i], GCRY_CIPHER_MODE_STREAM, 0); - if (algos2[i] == GCRY_CIPHER_CHACHA20 || - algos2[i] == GCRY_CIPHER_SALSA20 || - algos2[i] == GCRY_CIPHER_SALSA20R12) + if (algos2[i] == GCRY_CIPHER_CHACHA20) check_one_cipher (algos2[i], GCRY_CIPHER_MODE_POLY1305, 0); } /* we have now run all cipher's selftests */ diff --git a/tests/bench-slope.c b/tests/bench-slope.c index 7bf587f..ebf672e 100644 --- a/tests/bench-slope.c +++ b/tests/bench-slope.c @@ -1147,10 +1147,8 @@ cipher_bench_one (int algo, struct bench_cipher_mode *pmode) mode.name = mode.ops == &encrypt_ops ? "STREAM enc" : "STREAM dec"; } - /* Poly1305 has restrictions for cipher algorithm */ - if (mode.mode == GCRY_CIPHER_MODE_POLY1305 && - (algo != GCRY_CIPHER_SALSA20 && algo != GCRY_CIPHER_SALSA20R12 && - algo != GCRY_CIPHER_CHACHA20)) + /* Poly1305 has restriction for cipher algorithm */ + if (mode.mode == GCRY_CIPHER_MODE_POLY1305 && algo != GCRY_CIPHER_CHACHA20) return; /* CCM has restrictions for block-size */ From jussi.kivilinna at iki.fi Tue Dec 23 11:30:33 2014 From: jussi.kivilinna at iki.fi (Jussi Kivilinna) Date: Tue, 23 Dec 2014 12:30:33 +0200 Subject: [PATCH] rijndael: fix compiler warnings on ARM & PowerPC Message-ID: <20141223103033.13919.34125.stgit@localhost6.localdomain6> * cipher/rijndael-internal.h (RIJNDAEL_context_s): Add u32 variants of keyschedule arrays to unions u1 and u2. (keyschedenc32, keyscheddec32): New. * cipher/rijndael.c (u32_a_t): Remove. (do_setkey): Add and use tkk[].data32, k_u32, tk_u32 and W_u32; Remove casting byte arrays to u32_a_t. (prepare_decryption, do_encrypt_fn, do_decrypt_fn): Use keyschedenc32 and keyscheddec32; Remove casting byte arrays to u32_a_t. -- Patch fixes 'cast increases required alignment' compiler warnings that GCC was showing: rijndael.c: In function 'do_setkey': rijndael.c:310:13: warning: cast increases required alignment of target type [-Wcast-align] *((u32_a_t*)tk[j]) = *((u32_a_t*)k[j]); ^ rijndael.c:310:34: warning: cast increases required alignment of target type [-Wcast-align] *((u32_a_t*)tk[j]) = *((u32_a_t*)k[j]); Signed-off-by: Jussi Kivilinna --- cipher/rijndael-internal.h | 10 ++- cipher/rijndael.c | 137 ++++++++++++++++++++++---------------------- 2 files changed, 75 insertions(+), 72 deletions(-) diff --git a/cipher/rijndael-internal.h b/cipher/rijndael-internal.h index 7bc3790..7ff8660 100644 --- a/cipher/rijndael-internal.h +++ b/cipher/rijndael-internal.h @@ -95,6 +95,7 @@ typedef struct RIJNDAEL_context_s { PROPERLY_ALIGNED_TYPE dummy; byte keyschedule[MAXROUNDS+1][4][4]; + u32 keyschedule32[MAXROUNDS+1][4]; #ifdef USE_PADLOCK /* The key as passed to the padlock engine. It is only used if the padlock engine is used (USE_PADLOCK, below). */ @@ -105,6 +106,7 @@ typedef struct RIJNDAEL_context_s { PROPERLY_ALIGNED_TYPE dummy; byte keyschedule[MAXROUNDS+1][4][4]; + u32 keyschedule32[MAXROUNDS+1][4]; } u2; int rounds; /* Key-length-dependent number of rounds. */ unsigned int decryption_prepared:1; /* The decryption key schedule is available. */ @@ -121,8 +123,10 @@ typedef struct RIJNDAEL_context_s } RIJNDAEL_context ATTR_ALIGNED_16; /* Macros defining alias for the keyschedules. */ -#define keyschenc u1.keyschedule -#define keyschdec u2.keyschedule -#define padlockkey u1.padlock_key +#define keyschenc u1.keyschedule +#define keyschenc32 u1.keyschedule32 +#define keyschdec u2.keyschedule +#define keyschdec32 u2.keyschedule32 +#define padlockkey u1.padlock_key #endif /* G10_RIJNDAEL_INTERNAL_H */ diff --git a/cipher/rijndael.c b/cipher/rijndael.c index 5b0fe1c..7a83718 100644 --- a/cipher/rijndael.c +++ b/cipher/rijndael.c @@ -50,14 +50,6 @@ #include "rijndael-internal.h" -/* Define an u32 variant for the sake of gcc 4.4's strict aliasing. */ -#if __GNUC__ > 4 || ( __GNUC__ == 4 && __GNUC_MINOR__ >= 4 ) -typedef u32 __attribute__ ((__may_alias__)) u32_a_t; -#else -typedef u32 u32_a_t; -#endif - - #ifdef USE_AMD64_ASM /* AMD64 assembly implementations of AES */ extern unsigned int _gcry_aes_amd64_encrypt_block(const void *keysched_enc, @@ -293,10 +285,14 @@ do_setkey (RIJNDAEL_context *ctx, const byte *key, const unsigned keylen) { PROPERLY_ALIGNED_TYPE dummy; byte data[MAXKC][4]; + u32 data32[MAXKC]; } tkk[2]; -#define k tkk[0].data -#define tk tkk[1].data -#define W (ctx->keyschenc) +#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(); @@ -307,7 +303,7 @@ do_setkey (RIJNDAEL_context *ctx, const byte *key, const unsigned keylen) for (j = KC-1; j >= 0; j--) { - *((u32_a_t*)tk[j]) = *((u32_a_t*)k[j]); + tk_u32[j] = k_u32[j]; } r = 0; t = 0; @@ -316,7 +312,7 @@ do_setkey (RIJNDAEL_context *ctx, const byte *key, const unsigned keylen) { for (; (j < KC) && (t < 4); j++, t++) { - *((u32_a_t*)W[r][t]) = le_bswap32(*((u32_a_t*)tk[j])); + W_u32[r][t] = le_bswap32(tk_u32[j]); } if (t == 4) { @@ -339,14 +335,14 @@ do_setkey (RIJNDAEL_context *ctx, const byte *key, const unsigned keylen) { for (j = 1; j < KC; j++) { - *((u32_a_t*)tk[j]) ^= *((u32_a_t*)tk[j-1]); + tk_u32[j] ^= tk_u32[j-1]; } } else { for (j = 1; j < KC/2; j++) { - *((u32_a_t*)tk[j]) ^= *((u32_a_t*)tk[j-1]); + 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]; @@ -354,7 +350,7 @@ do_setkey (RIJNDAEL_context *ctx, const byte *key, const unsigned keylen) tk[KC/2][3] ^= sbox[tk[KC/2 - 1][3] * 4]; for (j = KC/2 + 1; j < KC; j++) { - *((u32_a_t*)tk[j]) ^= *((u32_a_t*)tk[j-1]); + tk_u32[j] ^= tk_u32[j-1]; } } @@ -363,7 +359,7 @@ do_setkey (RIJNDAEL_context *ctx, const byte *key, const unsigned keylen) { for (; (j < KC) && (t < 4); j++, t++) { - *((u32_a_t*)W[r][t]) = le_bswap32(*((u32_a_t*)tk[j])); + W_u32[r][t] = le_bswap32(tk_u32[j]); } if (t == 4) { @@ -375,6 +371,9 @@ do_setkey (RIJNDAEL_context *ctx, const byte *key, const unsigned keylen) #undef W #undef tk #undef k +#undef W_u32 +#undef tk_u32 +#undef k_u32 wipememory(&tkk, sizeof(tkk)); } @@ -417,15 +416,15 @@ prepare_decryption( RIJNDAEL_context *ctx ) prefetch_enc(); prefetch_dec(); - *((u32_a_t*)ctx->keyschdec[0][0]) = *((u32_a_t*)ctx->keyschenc[0][0]); - *((u32_a_t*)ctx->keyschdec[0][1]) = *((u32_a_t*)ctx->keyschenc[0][1]); - *((u32_a_t*)ctx->keyschdec[0][2]) = *((u32_a_t*)ctx->keyschenc[0][2]); - *((u32_a_t*)ctx->keyschdec[0][3]) = *((u32_a_t*)ctx->keyschenc[0][3]); + 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_a_t *wi = (u32_a_t*)((ctx->keyschenc)[r]); - u32_a_t *wo = (u32_a_t*)((ctx->keyschdec)[r]); + u32 *wi = ctx->keyschenc32[r]; + u32 *wo = ctx->keyschdec32[r]; u32 wt; wt = wi[0]; @@ -453,10 +452,10 @@ prepare_decryption( RIJNDAEL_context *ctx ) ^ rol(decT[sbox[(byte)(wt >> 24) * 4]], 8 * 3); } - *((u32_a_t*)ctx->keyschdec[r][0]) = *((u32_a_t*)ctx->keyschenc[r][0]); - *((u32_a_t*)ctx->keyschdec[r][1]) = *((u32_a_t*)ctx->keyschenc[r][1]); - *((u32_a_t*)ctx->keyschdec[r][2]) = *((u32_a_t*)ctx->keyschenc[r][2]); - *((u32_a_t*)ctx->keyschdec[r][3]) = *((u32_a_t*)ctx->keyschenc[r][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]; } } @@ -467,7 +466,7 @@ static unsigned int do_encrypt_fn (const RIJNDAEL_context *ctx, unsigned char *b, const unsigned char *a) { -#define rk (ctx->keyschenc) +#define rk (ctx->keyschenc32) const byte *sbox = ((const byte *)encT) + 1; int rounds = ctx->rounds; int r; @@ -479,34 +478,34 @@ do_encrypt_fn (const RIJNDAEL_context *ctx, unsigned char *b, sb[2] = buf_get_le32(a + 8); sb[3] = buf_get_le32(a + 12); - sa[0] = sb[0] ^ *((u32_a_t*)rk[0][0]); - sa[1] = sb[1] ^ *((u32_a_t*)rk[0][1]); - sa[2] = sb[2] ^ *((u32_a_t*)rk[0][2]); - sa[3] = sb[3] ^ *((u32_a_t*)rk[0][3]); + 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] = *((u32_a_t*)rk[1][0]) ^ sb[0]; + 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] = *((u32_a_t*)rk[1][1]) ^ sb[1]; + 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] = *((u32_a_t*)rk[1][2]) ^ sb[2]; + 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] = *((u32_a_t*)rk[1][3]) ^ sb[3]; + sa[3] = rk[1][3] ^ sb[3]; for (r = 2; r < rounds; r++) { @@ -514,25 +513,25 @@ do_encrypt_fn (const RIJNDAEL_context *ctx, unsigned char *b, 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] = *((u32_a_t*)rk[r][0]) ^ sb[0]; + 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] = *((u32_a_t*)rk[r][1]) ^ sb[1]; + 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] = *((u32_a_t*)rk[r][2]) ^ sb[2]; + 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] = *((u32_a_t*)rk[r][3]) ^ sb[3]; + sa[3] = rk[r][3] ^ sb[3]; r++; @@ -540,25 +539,25 @@ do_encrypt_fn (const RIJNDAEL_context *ctx, unsigned char *b, 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] = *((u32_a_t*)rk[r][0]) ^ sb[0]; + 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] = *((u32_a_t*)rk[r][1]) ^ sb[1]; + 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] = *((u32_a_t*)rk[r][2]) ^ sb[2]; + 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] = *((u32_a_t*)rk[r][3]) ^ sb[3]; + sa[3] = rk[r][3] ^ sb[3]; } /* Last round is special. */ @@ -567,25 +566,25 @@ do_encrypt_fn (const RIJNDAEL_context *ctx, unsigned char *b, sb[3] = (sbox[(byte)(sa[0] >> (1 * 8)) * 4]) << (1 * 8); sb[2] = (sbox[(byte)(sa[0] >> (2 * 8)) * 4]) << (2 * 8); sb[1] = (sbox[(byte)(sa[0] >> (3 * 8)) * 4]) << (3 * 8); - sa[0] = *((u32_a_t*)rk[r][0]) ^ sb[0]; + sa[0] = rk[r][0] ^ sb[0]; sb[1] ^= (sbox[(byte)(sa[1] >> (0 * 8)) * 4]) << (0 * 8); sa[0] ^= (sbox[(byte)(sa[1] >> (1 * 8)) * 4]) << (1 * 8); sb[3] ^= (sbox[(byte)(sa[1] >> (2 * 8)) * 4]) << (2 * 8); sb[2] ^= (sbox[(byte)(sa[1] >> (3 * 8)) * 4]) << (3 * 8); - sa[1] = *((u32_a_t*)rk[r][1]) ^ sb[1]; + sa[1] = rk[r][1] ^ sb[1]; sb[2] ^= (sbox[(byte)(sa[2] >> (0 * 8)) * 4]) << (0 * 8); sa[1] ^= (sbox[(byte)(sa[2] >> (1 * 8)) * 4]) << (1 * 8); sa[0] ^= (sbox[(byte)(sa[2] >> (2 * 8)) * 4]) << (2 * 8); sb[3] ^= (sbox[(byte)(sa[2] >> (3 * 8)) * 4]) << (3 * 8); - sa[2] = *((u32_a_t*)rk[r][2]) ^ sb[2]; + sa[2] = rk[r][2] ^ sb[2]; sb[3] ^= (sbox[(byte)(sa[3] >> (0 * 8)) * 4]) << (0 * 8); sa[2] ^= (sbox[(byte)(sa[3] >> (1 * 8)) * 4]) << (1 * 8); sa[1] ^= (sbox[(byte)(sa[3] >> (2 * 8)) * 4]) << (2 * 8); sa[0] ^= (sbox[(byte)(sa[3] >> (3 * 8)) * 4]) << (3 * 8); - sa[3] = *((u32_a_t*)rk[r][3]) ^ sb[3]; + sa[3] = rk[r][3] ^ sb[3]; buf_put_le32(b + 0, sa[0]); buf_put_le32(b + 4, sa[1]); @@ -790,7 +789,7 @@ static unsigned int do_decrypt_fn (const RIJNDAEL_context *ctx, unsigned char *b, const unsigned char *a) { -#define rk (ctx->keyschdec) +#define rk (ctx->keyschdec32) int rounds = ctx->rounds; int r; u32 sa[4]; @@ -801,10 +800,10 @@ do_decrypt_fn (const RIJNDAEL_context *ctx, unsigned char *b, sb[2] = buf_get_le32(a + 8); sb[3] = buf_get_le32(a + 12); - sa[0] = sb[0] ^ *((u32_a_t*)rk[rounds][0]); - sa[1] = sb[1] ^ *((u32_a_t*)rk[rounds][1]); - sa[2] = sb[2] ^ *((u32_a_t*)rk[rounds][2]); - sa[3] = sb[3] ^ *((u32_a_t*)rk[rounds][3]); + 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--) { @@ -812,25 +811,25 @@ do_decrypt_fn (const RIJNDAEL_context *ctx, unsigned char *b, 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] = *((u32_a_t*)rk[r][0]) ^ sb[0]; + 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] = *((u32_a_t*)rk[r][1]) ^ sb[1]; + 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] = *((u32_a_t*)rk[r][2]) ^ sb[2]; + 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] = *((u32_a_t*)rk[r][3]) ^ sb[3]; + sa[3] = rk[r][3] ^ sb[3]; r--; @@ -838,75 +837,75 @@ do_decrypt_fn (const RIJNDAEL_context *ctx, unsigned char *b, 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] = *((u32_a_t*)rk[r][0]) ^ sb[0]; + 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] = *((u32_a_t*)rk[r][1]) ^ sb[1]; + 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] = *((u32_a_t*)rk[r][2]) ^ sb[2]; + 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] = *((u32_a_t*)rk[r][3]) ^ sb[3]; + 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] = *((u32_a_t*)rk[1][0]) ^ sb[0]; + 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] = *((u32_a_t*)rk[1][1]) ^ sb[1]; + 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] = *((u32_a_t*)rk[1][2]) ^ sb[2]; + 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] = *((u32_a_t*)rk[1][3]) ^ sb[3]; + sa[3] = rk[1][3] ^ sb[3]; /* Last round is special. */ sb[0] = inv_sbox[(byte)(sa[0] >> (0 * 8))] << (0 * 8); sb[1] = inv_sbox[(byte)(sa[0] >> (1 * 8))] << (1 * 8); sb[2] = inv_sbox[(byte)(sa[0] >> (2 * 8))] << (2 * 8); sb[3] = inv_sbox[(byte)(sa[0] >> (3 * 8))] << (3 * 8); - sa[0] = sb[0] ^ *((u32_a_t*)rk[0][0]); + sa[0] = sb[0] ^ rk[0][0]; sb[1] ^= inv_sbox[(byte)(sa[1] >> (0 * 8))] << (0 * 8); sb[2] ^= inv_sbox[(byte)(sa[1] >> (1 * 8))] << (1 * 8); sb[3] ^= inv_sbox[(byte)(sa[1] >> (2 * 8))] << (2 * 8); sa[0] ^= inv_sbox[(byte)(sa[1] >> (3 * 8))] << (3 * 8); - sa[1] = sb[1] ^ *((u32_a_t*)rk[0][1]); + sa[1] = sb[1] ^ rk[0][1]; sb[2] ^= inv_sbox[(byte)(sa[2] >> (0 * 8))] << (0 * 8); sb[3] ^= inv_sbox[(byte)(sa[2] >> (1 * 8))] << (1 * 8); sa[0] ^= inv_sbox[(byte)(sa[2] >> (2 * 8))] << (2 * 8); sa[1] ^= inv_sbox[(byte)(sa[2] >> (3 * 8))] << (3 * 8); - sa[2] = sb[2] ^ *((u32_a_t*)rk[0][2]); + sa[2] = sb[2] ^ rk[0][2]; sb[3] ^= inv_sbox[(byte)(sa[3] >> (0 * 8))] << (0 * 8); sa[0] ^= inv_sbox[(byte)(sa[3] >> (1 * 8))] << (1 * 8); sa[1] ^= inv_sbox[(byte)(sa[3] >> (2 * 8))] << (2 * 8); sa[2] ^= inv_sbox[(byte)(sa[3] >> (3 * 8))] << (3 * 8); - sa[3] = sb[3] ^ *((u32_a_t*)rk[0][3]); + sa[3] = sb[3] ^ rk[0][3]; buf_put_le32(b + 0, sa[0]); buf_put_le32(b + 4, sa[1]); From jussi.kivilinna at iki.fi Tue Dec 23 16:36:21 2014 From: jussi.kivilinna at iki.fi (Jussi Kivilinna) Date: Tue, 23 Dec 2014 17:36:21 +0200 Subject: [PATCH 1/4] hash: fix compiler warning on ARM Message-ID: <20141223153621.8949.88773.stgit@localhost6.localdomain6> * cipher/md.c (md_open, md_copy): Cast 'char *' to ctx through 'void *'. * cipher/md4.c (md4_final): Use buf_put_* helper instead of converting 'char *' to 'u32 *'. * cipher/md5.c (md5_final): Ditto. * cipher/rmd160.c (_gcry_rmd160_mixblock, rmd160_final): Ditto. * cipher/sha1.c (sha1_final): Ditto. * cipher/sha256.c (sha256_final): Ditto. * cipher/sha512.c (sha512_final): Ditto. * cipher/tiger.c (tiger_final): Ditto. -- Patch fixes 'cast increases required alignment' warnings seen on GCC: md.c: In function 'md_open': md.c:318:23: warning: cast increases required alignment of target type [-Wcast-align] hd->ctx = ctx = (struct gcry_md_context *) ((char *) hd + n); ^ md.c: In function 'md_copy': md.c:491:22: warning: cast increases required alignment of target type [-Wcast-align] bhd->ctx = b = (struct gcry_md_context *) ((char *) bhd + n); ^ md4.c: In function 'md4_final': md4.c:258:20: warning: cast increases required alignment of target type [-Wcast-align] #define X(a) do { *(u32*)p = le_bswap32((*hd).a) ; p += 4; } while(0) ^ md4.c:259:3: note: in expansion of macro 'X' X(A); ^ md4.c:258:20: warning: cast increases required alignment of target type [-Wcast-align] #define X(a) do { *(u32*)p = le_bswap32((*hd).a) ; p += 4; } while(0) ^ md4.c:260:3: note: in expansion of macro 'X' X(B); ^ [removed the rest] Signed-off-by: Jussi Kivilinna --- cipher/md.c | 4 ++-- cipher/md4.c | 2 +- cipher/md5.c | 2 +- cipher/rmd160.c | 4 ++-- cipher/sha1.c | 2 +- cipher/sha256.c | 2 +- cipher/sha512.c | 2 +- cipher/tiger.c | 4 ++-- 8 files changed, 11 insertions(+), 11 deletions(-) diff --git a/cipher/md.c b/cipher/md.c index df8b027..f9414de 100644 --- a/cipher/md.c +++ b/cipher/md.c @@ -315,7 +315,7 @@ md_open (gcry_md_hd_t *h, int algo, unsigned int flags) if (! err) { - hd->ctx = ctx = (struct gcry_md_context *) ((char *) hd + n); + hd->ctx = ctx = (void *) ((char *) hd + n); /* Setup the globally visible data (bctl in the diagram).*/ hd->bufsize = n - sizeof (struct gcry_md_handle) + 1; hd->bufpos = 0; @@ -488,7 +488,7 @@ md_copy (gcry_md_hd_t ahd, gcry_md_hd_t *b_hd) if (! err) { - bhd->ctx = b = (struct gcry_md_context *) ((char *) bhd + n); + bhd->ctx = b = (void *) ((char *) bhd + n); /* No need to copy the buffer due to the write above. */ gcry_assert (ahd->bufsize == (n - sizeof (struct gcry_md_handle) + 1)); bhd->bufsize = ahd->bufsize; diff --git a/cipher/md4.c b/cipher/md4.c index 7291254..c9b4154 100644 --- a/cipher/md4.c +++ b/cipher/md4.c @@ -255,7 +255,7 @@ md4_final( void *context ) _gcry_burn_stack (burn); p = hd->bctx.buf; -#define X(a) do { *(u32*)p = le_bswap32((*hd).a) ; p += 4; } while(0) +#define X(a) do { buf_put_le32(p, hd->a); p += 4; } while(0) X(A); X(B); X(C); diff --git a/cipher/md5.c b/cipher/md5.c index 73ad968..f17af7a 100644 --- a/cipher/md5.c +++ b/cipher/md5.c @@ -279,7 +279,7 @@ md5_final( void *context) _gcry_burn_stack (burn); p = hd->bctx.buf; -#define X(a) do { *(u32*)p = le_bswap32((*hd).a) ; p += 4; } while(0) +#define X(a) do { buf_put_le32(p, hd->a); p += 4; } while(0) X(A); X(B); X(C); diff --git a/cipher/rmd160.c b/cipher/rmd160.c index e6d02f5..2b1f321 100644 --- a/cipher/rmd160.c +++ b/cipher/rmd160.c @@ -411,7 +411,7 @@ _gcry_rmd160_mixblock ( RMD160_CONTEXT *hd, void *blockof64byte ) char *p = blockof64byte; transform ( hd, blockof64byte, 1 ); -#define X(a) do { *(u32*)p = hd->h##a ; p += 4; } while(0) +#define X(a) do { buf_put_le32(p, hd->h##a); p += 4; } while(0) X(0); X(1); X(2); @@ -474,7 +474,7 @@ rmd160_final( void *context ) _gcry_burn_stack (burn); p = hd->bctx.buf; -#define X(a) do { *(u32*)p = le_bswap32(hd->h##a) ; p += 4; } while(0) +#define X(a) do { buf_put_le32(p, hd->h##a); p += 4; } while(0) X(0); X(1); X(2); diff --git a/cipher/sha1.c b/cipher/sha1.c index 00c57dd..6ccf0e8 100644 --- a/cipher/sha1.c +++ b/cipher/sha1.c @@ -401,7 +401,7 @@ sha1_final(void *context) _gcry_burn_stack (burn); p = hd->bctx.buf; -#define X(a) do { *(u32*)p = be_bswap32(hd->h##a) ; p += 4; } while(0) +#define X(a) do { buf_put_be32(p, hd->h##a); p += 4; } while(0) X(0); X(1); X(2); diff --git a/cipher/sha256.c b/cipher/sha256.c index 4efaec6..d3af172 100644 --- a/cipher/sha256.c +++ b/cipher/sha256.c @@ -428,7 +428,7 @@ sha256_final(void *context) _gcry_burn_stack (burn); p = hd->bctx.buf; -#define X(a) do { *(u32*)p = be_bswap32(hd->h##a); p += 4; } while(0) +#define X(a) do { buf_put_be32(p, hd->h##a); p += 4; } while(0) X(0); X(1); X(2); diff --git a/cipher/sha512.c b/cipher/sha512.c index 7d60df0..5a6af80 100644 --- a/cipher/sha512.c +++ b/cipher/sha512.c @@ -669,7 +669,7 @@ sha512_final (void *context) _gcry_burn_stack (stack_burn_depth); p = hd->bctx.buf; -#define X(a) do { *(u64*)p = be_bswap64(hd->state.h##a) ; p += 8; } while (0) +#define X(a) do { buf_put_be64(p, hd->state.h##a); p += 8; } while (0) X (0); X (1); X (2); diff --git a/cipher/tiger.c b/cipher/tiger.c index 91db4e6..8a08953 100644 --- a/cipher/tiger.c +++ b/cipher/tiger.c @@ -805,8 +805,8 @@ tiger_final( void *context ) _gcry_burn_stack (burn); p = hd->bctx.buf; -#define X(a) do { *(u64*)p = be_bswap64(hd->a); p += 8; } while(0) -#define Y(a) do { *(u64*)p = le_bswap64(hd->a); p += 8; } while(0) +#define X(a) do { buf_put_be64(p, hd->a); p += 8; } while(0) +#define Y(a) do { buf_put_le64(p, hd->a); p += 8; } while(0) if (hd->variant == 0) { X(a); From jussi.kivilinna at iki.fi Tue Dec 23 16:36:26 2014 From: jussi.kivilinna at iki.fi (Jussi Kivilinna) Date: Tue, 23 Dec 2014 17:36:26 +0200 Subject: [PATCH 2/4] secmem: fix compiler warnings on ARM In-Reply-To: <20141223153621.8949.88773.stgit@localhost6.localdomain6> References: <20141223153621.8949.88773.stgit@localhost6.localdomain6> Message-ID: <20141223153626.8949.909.stgit@localhost6.localdomain6> * src/secmem.c (ADDR_TO_BLOCK, mb_get_next, mb_get_new): Cast pointer from 'char *' to 'memblock_t *' through 'void *'. (MB_WIPE_OUT): Remove unneeded cast to 'memblock_t *'. -- Patch fixes 'cast increases required alignment' warnings seen on GCC: secmem.c: In function 'mb_get_next': secmem.c:140:13: warning: cast increases required alignment of target type [-Wcast-align] mb_next = (memblock_t *) ((char *) mb + BLOCK_HEAD_SIZE + mb->size); ^ secmem.c: In function 'mb_get_new': secmem.c:208:17: warning: cast increases required alignment of target type [-Wcast-align] mb_split = (memblock_t *) (((char *) mb) + BLOCK_HEAD_SIZE + size); ^ secmem.c: In function '_gcry_secmem_free_internal': secmem.c:101:3: warning: cast increases required alignment of target type [-Wcast-align] (memblock_t *) ((char *) addr - BLOCK_HEAD_SIZE) ^ secmem.c:603:8: note: in expansion of macro 'ADDR_TO_BLOCK' mb = ADDR_TO_BLOCK (a); ^ In file included from secmem.c:40:0: secmem.c:609:16: warning: cast increases required alignment of target type [-Wcast-align] wipememory2 ((memblock_t *) ((char *) mb + BLOCK_HEAD_SIZE), (byte), size); ^ g10lib.h:309:54: note: in definition of macro 'wipememory2' volatile char *_vptr=(volatile char *)(_ptr); \ ^ secmem.c:611:3: note: in expansion of macro 'MB_WIPE_OUT' MB_WIPE_OUT (0xff); ^ secmem.c:609:16: warning: cast increases required alignment of target type [-Wcast-align] wipememory2 ((memblock_t *) ((char *) mb + BLOCK_HEAD_SIZE), (byte), size); ^ g10lib.h:309:54: note: in definition of macro 'wipememory2' volatile char *_vptr=(volatile char *)(_ptr); \ ^ secmem.c:612:3: note: in expansion of macro 'MB_WIPE_OUT' MB_WIPE_OUT (0xaa); ^ secmem.c:609:16: warning: cast increases required alignment of target type [-Wcast-align] wipememory2 ((memblock_t *) ((char *) mb + BLOCK_HEAD_SIZE), (byte), size); ^ g10lib.h:309:54: note: in definition of macro 'wipememory2' volatile char *_vptr=(volatile char *)(_ptr); \ ^ secmem.c:613:3: note: in expansion of macro 'MB_WIPE_OUT' MB_WIPE_OUT (0x55); ^ secmem.c:609:16: warning: cast increases required alignment of target type [-Wcast-align] wipememory2 ((memblock_t *) ((char *) mb + BLOCK_HEAD_SIZE), (byte), size); ^ g10lib.h:309:54: note: in definition of macro 'wipememory2' volatile char *_vptr=(volatile char *)(_ptr); \ ^ secmem.c:614:3: note: in expansion of macro 'MB_WIPE_OUT' MB_WIPE_OUT (0x00); ^ secmem.c: In function '_gcry_secmem_realloc': secmem.c:644:8: warning: cast increases required alignment of target type [-Wcast-align] mb = (memblock_t *) ((char *) p - ((size_t) &((memblock_t *) 0)->aligned.c)); ^ Signed-off-by: Jussi Kivilinna --- src/secmem.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/secmem.c b/src/secmem.c index cfea921..df15df0 100644 --- a/src/secmem.c +++ b/src/secmem.c @@ -98,7 +98,7 @@ GPGRT_LOCK_DEFINE (secmem_lock); /* Convert an address into the according memory block structure. */ #define ADDR_TO_BLOCK(addr) \ - (memblock_t *) ((char *) addr - BLOCK_HEAD_SIZE) + (memblock_t *) (void *) ((char *) addr - BLOCK_HEAD_SIZE) /* Check whether P points into the pool. */ static int @@ -137,7 +137,7 @@ mb_get_next (memblock_t *mb) { memblock_t *mb_next; - mb_next = (memblock_t *) ((char *) mb + BLOCK_HEAD_SIZE + mb->size); + mb_next = (memblock_t *) (void *) ((char *) mb + BLOCK_HEAD_SIZE + mb->size); if (! ptr_into_pool_p (mb_next)) mb_next = NULL; @@ -205,7 +205,8 @@ mb_get_new (memblock_t *block, size_t size) { /* Split block. */ - mb_split = (memblock_t *) (((char *) mb) + BLOCK_HEAD_SIZE + size); + mb_split = (memblock_t *) (void *) (((char *) mb) + BLOCK_HEAD_SIZE + + size); mb_split->size = mb->size - size - BLOCK_HEAD_SIZE; mb_split->flags = 0; @@ -606,7 +607,7 @@ _gcry_secmem_free_internal (void *a) /* This does not make much sense: probably this memory is held in the * cache. We do it anyway: */ #define MB_WIPE_OUT(byte) \ - wipememory2 ((memblock_t *) ((char *) mb + BLOCK_HEAD_SIZE), (byte), size); + wipememory2 (((char *) mb + BLOCK_HEAD_SIZE), (byte), size); MB_WIPE_OUT (0xff); MB_WIPE_OUT (0xaa); @@ -641,7 +642,8 @@ _gcry_secmem_realloc (void *p, size_t newsize) SECMEM_LOCK; - mb = (memblock_t *) ((char *) p - ((size_t) &((memblock_t *) 0)->aligned.c)); + mb = (memblock_t *) (void *) ((char *) p + - ((size_t) &((memblock_t *) 0)->aligned.c)); size = mb->size; if (newsize < size) { From jussi.kivilinna at iki.fi Tue Dec 23 16:36:31 2014 From: jussi.kivilinna at iki.fi (Jussi Kivilinna) Date: Tue, 23 Dec 2014 17:36:31 +0200 Subject: [PATCH 3/4] scrypt: fix compiler warnings on ARM In-Reply-To: <20141223153621.8949.88773.stgit@localhost6.localdomain6> References: <20141223153621.8949.88773.stgit@localhost6.localdomain6> Message-ID: <20141223153631.8949.41723.stgit@localhost6.localdomain6> * cipher/scrypt.c (_scryptBlockMix): Cast X to 'u32 *' through 'void *'. -- Patch fixes 'cast increases required alignment' warnings seen on GCC: scrypt.c: In function '_scryptBlockMix': scrypt.c:145:22: warning: cast increases required alignment of target type [-Wcast-align] _salsa20_core ((u32*)X, (u32*)X, 8); ^ scrypt.c:145:31: warning: cast increases required alignment of target type [-Wcast-align] _salsa20_core ((u32*)X, (u32*)X, 8); ^ Signed-off-by: Jussi Kivilinna --- cipher/scrypt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cipher/scrypt.c b/cipher/scrypt.c index 404943d..aca903d 100644 --- a/cipher/scrypt.c +++ b/cipher/scrypt.c @@ -142,7 +142,7 @@ _scryptBlockMix (u32 r, unsigned char *B, unsigned char *tmp2) buf_xor(X, X, &B[i * 64], 64); /* X = Salsa (T) */ - _salsa20_core ((u32*)X, (u32*)X, 8); + _salsa20_core ((u32*)(void*)X, (u32*)(void*)X, 8); /* Y[i] = X */ memcpy (&Y[i * 64], X, 64); From jussi.kivilinna at iki.fi Tue Dec 23 16:36:36 2014 From: jussi.kivilinna at iki.fi (Jussi Kivilinna) Date: Tue, 23 Dec 2014 17:36:36 +0200 Subject: [PATCH 4/4] random-csprng: fix compiler warnings on ARM In-Reply-To: <20141223153621.8949.88773.stgit@localhost6.localdomain6> References: <20141223153621.8949.88773.stgit@localhost6.localdomain6> Message-ID: <20141223153636.8949.87271.stgit@localhost6.localdomain6> * random/random-csprng.c (_gcry_rngcsprng_update_seed_file) (read_pool): Cast keypool and rndpool to 'unsigned long *' through 'void *'. -- Patch fixes 'cast increases required alignment' warnings seen on GCC: random-csprng.c: In function '_gcry_rngcsprng_update_seed_file': random-csprng.c:867:15: warning: cast increases required alignment of target type [-Wcast-align] for (i=0,dp=(unsigned long*)keypool, sp=(unsigned long*)rndpool; ^ random-csprng.c:867:43: warning: cast increases required alignment of target type [-Wcast-align] for (i=0,dp=(unsigned long*)keypool, sp=(unsigned long*)rndpool; ^ random-csprng.c: In function 'read_pool': random-csprng.c:1023:14: warning: cast increases required alignment of target type [-Wcast-align] for(i=0,dp=(unsigned long*)keypool, sp=(unsigned long*)rndpool; ^ random-csprng.c:1023:42: warning: cast increases required alignment of target type [-Wcast-align] for(i=0,dp=(unsigned long*)keypool, sp=(unsigned long*)rndpool; ^ Signed-off-by: Jussi Kivilinna --- random/random-csprng.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/random/random-csprng.c b/random/random-csprng.c index 429c84f..332744b 100644 --- a/random/random-csprng.c +++ b/random/random-csprng.c @@ -864,7 +864,7 @@ _gcry_rngcsprng_update_seed_file (void) /* Copy the entropy pool to a scratch pool and mix both of them. */ - for (i=0,dp=(unsigned long*)keypool, sp=(unsigned long*)rndpool; + for (i=0,dp=(unsigned long*)(void*)keypool, sp=(unsigned long*)(void*)rndpool; i < POOLWORDS; i++, dp++, sp++ ) { *dp = *sp + ADD_VALUE; @@ -1020,7 +1020,7 @@ read_pool (byte *buffer, size_t length, int level) } /* Create a new pool. */ - for(i=0,dp=(unsigned long*)keypool, sp=(unsigned long*)rndpool; + for(i=0,dp=(unsigned long*)(void*)keypool, sp=(unsigned long*)(void*)rndpool; i < POOLWORDS; i++, dp++, sp++ ) *dp = *sp + ADD_VALUE; From git at internot.info Sun Dec 28 06:59:51 2014 From: git at internot.info (Joshua Rogers) Date: Sun, 28 Dec 2014 16:59:51 +1100 Subject: [PATCH] * Avoid potential out-of-bounds read, due to incorrect checking. Message-ID: <1419746391-6713-1-git-send-email-git@internot.info> * mpi/mpiutil.c (_gcry_mpi_const): Check 'no' against => MPI_NUMBER_OF_CONSTANTS to avoid a potential out-of-bounds read -- Signed-off-by: Joshua Rogers --- mpi/mpiutil.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mpi/mpiutil.c b/mpi/mpiutil.c index f74dd91..0a833d2 100644 --- a/mpi/mpiutil.c +++ b/mpi/mpiutil.c @@ -690,7 +690,7 @@ _gcry_mpi_get_flag (gcry_mpi_t a, enum gcry_mpi_flag flag) gcry_mpi_t _gcry_mpi_const (enum gcry_mpi_constants no) { - if ((int)no < 0 || no > MPI_NUMBER_OF_CONSTANTS) + if ((int)no < 0 || no >= MPI_NUMBER_OF_CONSTANTS) log_bug("invalid mpi_const selector %d\n", no); if (!constants[no]) log_bug("MPI subsystem not initialized\n"); -- 1.9.1 From git at internot.info Sun Dec 28 06:43:03 2014 From: git at internot.info (Joshua Rogers) Date: Sun, 28 Dec 2014 16:43:03 +1100 Subject: [PATCH] * avoid double-free on gcry_hmac256_finalize(gcry_hmac256_new) failure Message-ID: <1419745383-6446-1-git-send-email-git@internot.info> * src/hmac256.c (gcry_hmac256_new): if gcry_hmac256_finalize fails, avoid double-free of hd. -- Signed-off-by: Joshua Rogers --- src/hmac256.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/hmac256.c b/src/hmac256.c index 94a26da..7fbd321 100644 --- a/src/hmac256.c +++ b/src/hmac256.c @@ -496,7 +496,8 @@ _gcry_hmac256_file (void *result, size_t resultsize, const char *filename, digest = _gcry_hmac256_finalize (hd, &digestlen); if (!digest) { - _gcry_hmac256_release (hd); + if(hd) + _gcry_hmac256_release (hd); return -1; } -- 1.9.1 From git at internot.info Sun Dec 28 06:29:14 2014 From: git at internot.info (Joshua Rogers) Date: Sun, 28 Dec 2014 16:29:14 +1100 Subject: * Fix incorrect order, passing of variables to m_out_of_n, in prime_generate_internal(). Message-ID: <1419744554-6148-1-git-send-email-git@internot.info> * cipher/primegen.c (prime_generate_internal): Correctly pass 'm' and 'n' to the m_out_of_n function. -- Signed-off-by: Joshua Rogers --- cipher/primegen.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cipher/primegen.c b/cipher/primegen.c index ce6db8d..55bfc1d 100644 --- a/cipher/primegen.c +++ b/cipher/primegen.c @@ -484,7 +484,7 @@ prime_generate_internal (int need_q_factor, else { /* Get next permutation. */ - m_out_of_n ( (char*)perms, n, m); + m_out_of_n ( (char*)perms, m, n); if ((err = gpgrt_lock_lock (&primepool_lock))) goto leave; -- 1.9.1 From git at internot.info Sun Dec 28 08:19:17 2014 From: git at internot.info (Joshua Rogers) Date: Sun, 28 Dec 2014 18:19:17 +1100 Subject: Explicit overflow / incorrect code? Message-ID: <549FAEF5.9010008@internot.info> Hi, In /cipher/gostr3411-94.c: 310 for (i = 1; i < 32 && nblocks != 0; i++) 311 { 312 l[i] = nblocks; But in /cipher/gostr3411-94.c: 284 u32 l[8]; I believe it should be: for (i = *0*; i < *8* && nblocks != 0; i++) right? Thanks, -- -- Joshua Rogers -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 819 bytes Desc: OpenPGP digital signature URL: From honey at internot.info Sun Dec 28 06:57:20 2014 From: honey at internot.info (Joshua Rogers) Date: Sun, 28 Dec 2014 16:57:20 +1100 Subject: Explicit overflow / incorrect code? Message-ID: <549F9BC0.3010002@internot.info> Hi, In /cipher/gostr3411-94.c: 310 for (i = 1; i < 32 && nblocks != 0; i++) 311 { 312 l[i] = nblocks; But in /cipher/gostr3411-94.c: 284 u32 l[8]; I believe it should be: for (i = *0*; i < *8* && nblocks != 0; i++) right? Thanks, -- -- Joshua Rogers -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 819 bytes Desc: OpenPGP digital signature URL: From dbaryshkov at gmail.com Sun Dec 28 10:01:42 2014 From: dbaryshkov at gmail.com (Dmitry Eremin-Solenikov) Date: Sun, 28 Dec 2014 13:01:42 +0400 Subject: Explicit overflow / incorrect code? In-Reply-To: <549F9BC0.3010002@internot.info> References: <549F9BC0.3010002@internot.info> Message-ID: Hello, 2014-12-28 8:57 GMT+03:00 Joshua Rogers : > Hi, > > In /cipher/gostr3411-94.c: > > 310 for (i = 1; i < 32 && nblocks != 0; i++) > 311 { > 312 l[i] = nblocks; > > But in > /cipher/gostr3411-94.c: > 284 u32 l[8]; > > > I believe it should be: > for (i = *0*; i < *8* && nblocks != 0; i++) Not quite, thanks for noticing though. I'll send a patch shortly. -- With best wishes Dmitry From dbaryshkov at gmail.com Sun Dec 28 10:05:43 2014 From: dbaryshkov at gmail.com (Dmitry Eremin-Solenikov) Date: Sun, 28 Dec 2014 12:05:43 +0300 Subject: [PATCH] gostr3411-94: fix the iteration count for length filling loop Message-ID: <1419757543-15954-1-git-send-email-dbaryshkov@gmail.com> The maximum iteration count for filling the l (bit length) array was incrrectly set to 32 (missed that in u8->u32 refactoring). This was not resulting in stack corruption, since nblocks variable would be exausted earlier compared to 8 32-bit values (the size of the array). Signed-off-by: Dmitry Eremin-Solenikov --- cipher/gostr3411-94.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cipher/gostr3411-94.c b/cipher/gostr3411-94.c index 91e5b4c..7b16e61 100644 --- a/cipher/gostr3411-94.c +++ b/cipher/gostr3411-94.c @@ -307,7 +307,7 @@ gost3411_final (void *context) l[0] |= nblocks << 8; nblocks >>= 24; - for (i = 1; i < 32 && nblocks != 0; i++) + for (i = 1; i < 8 && nblocks != 0; i++) { l[i] = nblocks; nblocks >>= 24; -- 2.1.4 From dbaryshkov at gmail.com Sun Dec 28 10:15:33 2014 From: dbaryshkov at gmail.com (Dmitry Eremin-Solenikov) Date: Sun, 28 Dec 2014 12:15:33 +0300 Subject: [PATCH] Stribog: fix C16 table size Message-ID: <1419758133-26930-1-git-send-email-dbaryshkov@gmail.com> Signed-off-by: Dmitry Eremin-Solenikov --- cipher/stribog.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cipher/stribog.c b/cipher/stribog.c index 942bbf4..de167a7 100644 --- a/cipher/stribog.c +++ b/cipher/stribog.c @@ -1080,7 +1080,7 @@ static const u64 stribog_table[8][256] = U64_C(0x72d14d3493b2e388), U64_C(0xd6a30f258c153427) }, }; -static const u64 C16[13][16] = +static const u64 C16[12][8] = { { U64_C(0xdd806559f2a64507), U64_C(0x05767436cc744d23), U64_C(0xa2422a08a460d315), U64_C(0x4b7ce09192676901), -- 2.1.4 From cvs at cvs.gnupg.org Sun Dec 28 14:57:43 2014 From: cvs at cvs.gnupg.org (by Jussi Kivilinna) Date: Sun, 28 Dec 2014 14:57:43 +0100 Subject: [git] GCRYPT - branch, master, updated. libgcrypt-1.6.0-139-g520070e Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU crypto library". The branch, master has been updated via 520070e02e2e6ee7228945015573a6e1f4895ec3 (commit) via 11b8d2d449a7bc664b4371ae14c57caa6704d272 (commit) from c964321c8a1328e89d636d899a45d68802f5ac9f (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 520070e02e2e6ee7228945015573a6e1f4895ec3 Author: Jussi Kivilinna Date: Sun Dec 21 17:36:59 2014 +0200 Poly1305-AEAD: updated implementation to match draft-irtf-cfrg-chacha20-poly1305-03 * cipher/cipher-internal.h (gcry_cipher_handle): Use separate byte counters for AAD and data in Poly1305. * cipher/cipher-poly1305.c (poly1305_fill_bytecount): Remove. (poly1305_fill_bytecounts, poly1305_do_padding): New. (poly1305_aad_finish): Fill padding to Poly1305 and do not fill AAD length. (_gcry_cipher_poly1305_authenticate, _gcry_cipher_poly1305_encrypt) (_gcry_cipher_poly1305_decrypt): Update AAD and data length separately. (_gcry_cipher_poly1305_tag): Fill padding and bytecounts to Poly1305. (_gcry_cipher_poly1305_setkey, _gcry_cipher_poly1305_setiv): Reset AAD and data byte counts; only allow 96-bit IV. * cipher/cipher.c (_gcry_cipher_open_internal): Limit Poly1305-AEAD to ChaCha20 cipher. * tests/basic.c (_check_poly1305_cipher): Update test-vectors. (check_ciphers): Limit Poly1305-AEAD checks to ChaCha20. * tests/bench-slope.c (cipher_bench_one): Ditto. -- Latest Internet-Draft version for "ChaCha20 and Poly1305 for IETF protocols" has added additional padding to Poly1305-AEAD and limited support IV size to 96-bits: https://www.ietf.org/rfcdiff?url1=draft-nir-cfrg-chacha20-poly1305-03&difftype=--html&submit=Go!&url2=draft-irtf-cfrg-chacha20-poly1305-03 Patch makes Poly1305-AEAD implementation to match the changes and limits Poly1305-AEAD to ChaCha20 only. Signed-off-by: Jussi Kivilinna diff --git a/cipher/cipher-internal.h b/cipher/cipher-internal.h index fef0ecb..650d813 100644 --- a/cipher/cipher-internal.h +++ b/cipher/cipher-internal.h @@ -163,8 +163,11 @@ struct gcry_cipher_handle /* Mode specific storage for Poly1305 mode. */ struct { - /* byte counter for AAD and data. */ - u32 bytecount[2]; + /* 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; diff --git a/cipher/cipher-poly1305.c b/cipher/cipher-poly1305.c index a22ffa3..f283333 100644 --- a/cipher/cipher-poly1305.c +++ b/cipher/cipher-poly1305.c @@ -53,12 +53,14 @@ poly1305_bytecounter_add (u32 ctr[2], size_t add) static void -poly1305_fill_bytecount (gcry_cipher_hd_t c) +poly1305_fill_bytecounts (gcry_cipher_hd_t c) { - u32 lenbuf[2]; + u32 lenbuf[4]; - lenbuf[0] = le_bswap32(c->u_mode.poly1305.bytecount[0]); - lenbuf[1] = le_bswap32(c->u_mode.poly1305.bytecount[1]); + lenbuf[0] = le_bswap32(c->u_mode.poly1305.aadcount[0]); + lenbuf[1] = le_bswap32(c->u_mode.poly1305.aadcount[1]); + lenbuf[2] = le_bswap32(c->u_mode.poly1305.datacount[0]); + lenbuf[3] = le_bswap32(c->u_mode.poly1305.datacount[1]); _gcry_poly1305_update (&c->u_mode.poly1305.ctx, (byte*)lenbuf, sizeof(lenbuf)); @@ -67,15 +69,33 @@ poly1305_fill_bytecount (gcry_cipher_hd_t c) static void +poly1305_do_padding (gcry_cipher_hd_t c, u32 ctr[2]) +{ + static const byte zero_padding_buf[15] = {}; + u32 padding_count; + + /* Padding to 16 byte boundary. */ + if (ctr[0] % 16 > 0) + { + padding_count = 16 - ctr[0] % 16; + + _gcry_poly1305_update (&c->u_mode.poly1305.ctx, zero_padding_buf, + padding_count); + } +} + + +static void poly1305_aad_finish (gcry_cipher_hd_t c) { - /* Start of encryption marks end of AAD stream. */ - poly1305_fill_bytecount(c); + /* After AAD, feed padding bytes so we get 16 byte alignment. */ + poly1305_do_padding (c, c->u_mode.poly1305.aadcount); + /* Start of encryption marks end of AAD stream. */ c->u_mode.poly1305.aad_finalized = 1; - c->u_mode.poly1305.bytecount[0] = 0; - c->u_mode.poly1305.bytecount[1] = 0; + c->u_mode.poly1305.datacount[0] = 0; + c->u_mode.poly1305.datacount[1] = 0; } @@ -102,7 +122,7 @@ _gcry_cipher_poly1305_authenticate (gcry_cipher_hd_t c, if (!c->marks.iv) poly1305_set_zeroiv(c); - if (poly1305_bytecounter_add(c->u_mode.poly1305.bytecount, aadbuflen)) + if (poly1305_bytecounter_add(c->u_mode.poly1305.aadcount, aadbuflen)) { c->u_mode.poly1305.bytecount_over_limits = 1; return GPG_ERR_INV_LENGTH; @@ -138,7 +158,7 @@ _gcry_cipher_poly1305_encrypt (gcry_cipher_hd_t c, if (!c->u_mode.poly1305.aad_finalized) poly1305_aad_finish(c); - if (poly1305_bytecounter_add(c->u_mode.poly1305.bytecount, inbuflen)) + if (poly1305_bytecounter_add(c->u_mode.poly1305.datacount, inbuflen)) { c->u_mode.poly1305.bytecount_over_limits = 1; return GPG_ERR_INV_LENGTH; @@ -176,7 +196,7 @@ _gcry_cipher_poly1305_decrypt (gcry_cipher_hd_t c, if (!c->u_mode.poly1305.aad_finalized) poly1305_aad_finish(c); - if (poly1305_bytecounter_add(c->u_mode.poly1305.bytecount, inbuflen)) + if (poly1305_bytecounter_add(c->u_mode.poly1305.datacount, inbuflen)) { c->u_mode.poly1305.bytecount_over_limits = 1; return GPG_ERR_INV_LENGTH; @@ -212,8 +232,11 @@ _gcry_cipher_poly1305_tag (gcry_cipher_hd_t c, if (!c->marks.tag) { - /* Write data-length to poly1305. */ - poly1305_fill_bytecount(c); + /* After data, feed padding bytes so we get 16 byte alignment. */ + poly1305_do_padding (c, c->u_mode.poly1305.datacount); + + /* Write byte counts to poly1305. */ + poly1305_fill_bytecounts(c); _gcry_poly1305_finish(&c->u_mode.poly1305.ctx, c->u_iv.iv); @@ -247,8 +270,11 @@ _gcry_cipher_poly1305_check_tag (gcry_cipher_hd_t c, const unsigned char *intag, void _gcry_cipher_poly1305_setkey (gcry_cipher_hd_t c) { - c->u_mode.poly1305.bytecount[0] = 0; - c->u_mode.poly1305.bytecount[1] = 0; + c->u_mode.poly1305.aadcount[0] = 0; + c->u_mode.poly1305.aadcount[1] = 0; + + c->u_mode.poly1305.datacount[0] = 0; + c->u_mode.poly1305.datacount[1] = 0; c->u_mode.poly1305.bytecount_over_limits = 0; c->u_mode.poly1305.aad_finalized = 0; @@ -260,16 +286,20 @@ _gcry_cipher_poly1305_setkey (gcry_cipher_hd_t c) gcry_err_code_t _gcry_cipher_poly1305_setiv (gcry_cipher_hd_t c, const byte *iv, size_t ivlen) { - byte tmpbuf[64]; /* size of ChaCha20/Salsa20 block */ + byte tmpbuf[64]; /* size of ChaCha20 block */ gcry_err_code_t err; - if (!iv && ivlen > 0) + /* IV must be 96-bits */ + if (!iv && ivlen != (96 / 8)) return GPG_ERR_INV_ARG; memset(&c->u_mode.poly1305.ctx, 0, sizeof(c->u_mode.poly1305.ctx)); - c->u_mode.poly1305.bytecount[0] = 0; - c->u_mode.poly1305.bytecount[1] = 0; + c->u_mode.poly1305.aadcount[0] = 0; + c->u_mode.poly1305.aadcount[1] = 0; + + c->u_mode.poly1305.datacount[0] = 0; + c->u_mode.poly1305.datacount[1] = 0; c->u_mode.poly1305.bytecount_over_limits = 0; c->u_mode.poly1305.aad_finalized = 0; @@ -279,7 +309,7 @@ _gcry_cipher_poly1305_setiv (gcry_cipher_hd_t c, const byte *iv, size_t ivlen) /* Set up IV for stream cipher. */ c->spec->setiv (&c->context.c, iv, ivlen); - /* Get the first block from ChaCha20/Salsa20. */ + /* Get the first block from ChaCha20. */ memset(tmpbuf, 0, sizeof(tmpbuf)); c->spec->stencrypt(&c->context.c, tmpbuf, tmpbuf, sizeof(tmpbuf)); diff --git a/cipher/cipher.c b/cipher/cipher.c index 5c44c0d..78cad21 100644 --- a/cipher/cipher.c +++ b/cipher/cipher.c @@ -421,9 +421,7 @@ _gcry_cipher_open_internal (gcry_cipher_hd_t *handle, case GCRY_CIPHER_MODE_POLY1305: if (!spec->stencrypt || !spec->stdecrypt || !spec->setiv) err = GPG_ERR_INV_CIPHER_MODE; - else if (spec->algo != GCRY_CIPHER_SALSA20 && - spec->algo != GCRY_CIPHER_SALSA20R12 && - spec->algo != GCRY_CIPHER_CHACHA20) + else if (spec->algo != GCRY_CIPHER_CHACHA20) err = GPG_ERR_INV_CIPHER_MODE; break; diff --git a/tests/basic.c b/tests/basic.c index e406db4..ef8260f 100644 --- a/tests/basic.c +++ b/tests/basic.c @@ -1625,27 +1625,59 @@ _check_poly1305_cipher (unsigned int step) struct tv { int algo; - char key[MAX_DATA_LEN]; - char iv[MAX_DATA_LEN]; + const char *key; + const char *iv; int ivlen; - unsigned char aad[MAX_DATA_LEN]; + const char *aad; int aadlen; - unsigned char plaintext[MAX_DATA_LEN]; + const char *plaintext; int inlen; - char out[MAX_DATA_LEN]; - char tag[MAX_DATA_LEN]; + const char *out; + const char *tag; } tv[] = { - /* draft-agl-tls-chacha20poly1305-04 */ + /* draft-irtf-cfrg-chacha20-poly1305-03 */ { GCRY_CIPHER_CHACHA20, - "\x42\x90\xbc\xb1\x54\x17\x35\x31\xf3\x14\xaf\x57\xf3\xbe\x3b\x50" - "\x06\xda\x37\x1e\xce\x27\x2a\xfa\x1b\x5d\xbd\xd1\x10\x0a\x10\x07", - "\xcd\x7c\xf6\x7b\xe3\x9c\x79\x4a", 8, - "\x87\xe2\x29\xd4\x50\x08\x45\xa0\x79\xc0", 10, - "\x86\xd0\x99\x74\x84\x0b\xde\xd2\xa5\xca", 10, - "\xe3\xe4\x46\xf7\xed\xe9\xa1\x9b\x62\xa4", - "\x67\x7d\xab\xf4\xe3\xd2\x4b\x87\x6b\xb2\x84\x75\x38\x96\xe1\xd6" }, - /* draft-nir-cfrg-chacha20-poly1305-03 */ + "\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", @@ -1661,11 +1693,11 @@ _check_poly1305_cipher (unsigned int step) "\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", - "\x18\xfb\x11\xa5\x03\x1a\xd1\x3a\x7e\x3b\x03\xd4\x6e\xe3\xa6\xa7" } + "\x1a\xe1\x0b\x59\x4f\x09\xe2\x6a\x7e\x90\x2e\xcb\xd0\x60\x06\x91" }, }; gcry_cipher_hd_t hde, hdd; - unsigned char out[MAX_DATA_LEN]; + unsigned char out[1024]; unsigned char tag[16]; int i, keylen; gcry_error_t err = 0; @@ -4333,9 +4365,7 @@ check_ciphers (void) gcry_cipher_algo_name (algos2[i])); check_one_cipher (algos2[i], GCRY_CIPHER_MODE_STREAM, 0); - if (algos2[i] == GCRY_CIPHER_CHACHA20 || - algos2[i] == GCRY_CIPHER_SALSA20 || - algos2[i] == GCRY_CIPHER_SALSA20R12) + if (algos2[i] == GCRY_CIPHER_CHACHA20) check_one_cipher (algos2[i], GCRY_CIPHER_MODE_POLY1305, 0); } /* we have now run all cipher's selftests */ diff --git a/tests/bench-slope.c b/tests/bench-slope.c index 7bf587f..ebf672e 100644 --- a/tests/bench-slope.c +++ b/tests/bench-slope.c @@ -1147,10 +1147,8 @@ cipher_bench_one (int algo, struct bench_cipher_mode *pmode) mode.name = mode.ops == &encrypt_ops ? "STREAM enc" : "STREAM dec"; } - /* Poly1305 has restrictions for cipher algorithm */ - if (mode.mode == GCRY_CIPHER_MODE_POLY1305 && - (algo != GCRY_CIPHER_SALSA20 && algo != GCRY_CIPHER_SALSA20R12 && - algo != GCRY_CIPHER_CHACHA20)) + /* Poly1305 has restriction for cipher algorithm */ + if (mode.mode == GCRY_CIPHER_MODE_POLY1305 && algo != GCRY_CIPHER_CHACHA20) return; /* CCM has restrictions for block-size */ commit 11b8d2d449a7bc664b4371ae14c57caa6704d272 Author: Jussi Kivilinna Date: Sun Dec 21 17:36:59 2014 +0200 chacha20: allow setting counter for stream random access * cipher/chacha20.c (CHACHA20_CTR_SIZE): New. (chacha20_ivsetup): Add setup for full counter. (chacha20_setiv): Allow ivlen == CHACHA20_CTR_SIZE. -- Signed-off-by: Jussi Kivilinna diff --git a/cipher/chacha20.c b/cipher/chacha20.c index c1847aa..2eaeffd 100644 --- a/cipher/chacha20.c +++ b/cipher/chacha20.c @@ -45,6 +45,7 @@ #define CHACHA20_BLOCK_SIZE 64 /* Bytes. */ #define CHACHA20_MIN_IV_SIZE 8 /* Bytes. */ #define CHACHA20_MAX_IV_SIZE 12 /* Bytes. */ +#define CHACHA20_CTR_SIZE 16 /* Bytes. */ #define CHACHA20_INPUT_LENGTH (CHACHA20_BLOCK_SIZE / 4) /* USE_SSE2 indicates whether to compile with Intel SSE2 code. */ @@ -312,22 +313,30 @@ chacha20_keysetup (CHACHA20_context_t * ctx, const byte * key, static void chacha20_ivsetup (CHACHA20_context_t * ctx, const byte * iv, size_t ivlen) { - ctx->input[12] = 0; - - if (ivlen == CHACHA20_MAX_IV_SIZE) + if (ivlen == CHACHA20_CTR_SIZE) + { + ctx->input[12] = buf_get_le32 (iv + 0); + ctx->input[13] = buf_get_le32 (iv + 4); + ctx->input[14] = buf_get_le32 (iv + 8); + ctx->input[15] = buf_get_le32 (iv + 12); + } + else if (ivlen == CHACHA20_MAX_IV_SIZE) { + ctx->input[12] = 0; ctx->input[13] = buf_get_le32 (iv + 0); ctx->input[14] = buf_get_le32 (iv + 4); ctx->input[15] = buf_get_le32 (iv + 8); } else if (ivlen == CHACHA20_MIN_IV_SIZE) { + ctx->input[12] = 0; ctx->input[13] = 0; ctx->input[14] = buf_get_le32 (iv + 0); ctx->input[15] = buf_get_le32 (iv + 4); } else { + ctx->input[12] = 0; ctx->input[13] = 0; ctx->input[14] = 0; ctx->input[15] = 0; @@ -402,10 +411,12 @@ chacha20_setiv (void *context, const byte * iv, size_t ivlen) CHACHA20_context_t *ctx = (CHACHA20_context_t *) context; /* draft-nir-cfrg-chacha20-poly1305-02 defines 96-bit and 64-bit nonce. */ - if (iv && ivlen != CHACHA20_MAX_IV_SIZE && ivlen != CHACHA20_MIN_IV_SIZE) + if (iv && ivlen != CHACHA20_MAX_IV_SIZE && ivlen != CHACHA20_MIN_IV_SIZE + && ivlen != CHACHA20_CTR_SIZE) log_info ("WARNING: chacha20_setiv: bad ivlen=%u\n", (u32) ivlen); - if (iv && (ivlen == CHACHA20_MAX_IV_SIZE || ivlen == CHACHA20_MIN_IV_SIZE)) + if (iv && (ivlen == CHACHA20_MAX_IV_SIZE || ivlen == CHACHA20_MIN_IV_SIZE + || ivlen == CHACHA20_CTR_SIZE)) chacha20_ivsetup (ctx, iv, ivlen); else chacha20_ivsetup (ctx, NULL, 0); ----------------------------------------------------------------------- Summary of changes: cipher/chacha20.c | 21 ++++++++++---- cipher/cipher-internal.h | 7 +++-- cipher/cipher-poly1305.c | 70 +++++++++++++++++++++++++++++++++------------- cipher/cipher.c | 4 +-- tests/basic.c | 70 +++++++++++++++++++++++++++++++++------------- tests/bench-slope.c | 6 ++-- 6 files changed, 124 insertions(+), 54 deletions(-) hooks/post-receive -- The GNU crypto library http://git.gnupg.org _______________________________________________ Gnupg-commits mailing list Gnupg-commits at gnupg.org http://lists.gnupg.org/mailman/listinfo/gnupg-commits From jussi.kivilinna at iki.fi Sun Dec 28 15:03:10 2014 From: jussi.kivilinna at iki.fi (Jussi Kivilinna) Date: Sun, 28 Dec 2014 16:03:10 +0200 Subject: [PATCH] Add Intel SSSE3 based vector permutation AES implementation Message-ID: <20141228140310.30327.87936.stgit@localhost6.localdomain6> * cipher/Makefile.am: Add 'rijndael-ssse3-amd64.c'. * cipher/rijndael-internal.h (USE_SSSE3): New. (RIJNDAEL_context_s) [USE_SSSE3]: Add 'use_ssse3'. * cipher/rijndael-ssse3-amd64.c: New. * cipher/rijndael.c [USE_SSSE3] (_gcry_aes_ssse3_do_setkey) (_gcry_aes_ssse3_prepare_decryption, _gcry_aes_ssse3_encrypt) (_gcry_aes_ssse3_decrypt, _gcry_aes_ssse3_cfb_enc) (_gcry_aes_ssse3_cbc_enc, _gcry_aes_ssse3_ctr_enc) (_gcry_aes_ssse3_cfb_dec, _gcry_aes_ssse3_cbc_dec): New. (do_setkey): Add HWF check for SSSE3 and setup for SSSE3 implementation. (prepare_decryption, _gcry_aes_cfb_enc, _gcry_aes_cbc_enc) (_gcry_aes_ctr_enc, _gcry_aes_cfb_dec, _gcry_aes_cbc_dec): Add selection for SSSE3 implementation. * configure.ac [host=x86_64]: Add 'rijndael-ssse3-amd64.lo'. -- This patch adds "AES with vector permutations" implementation by Mike Hamburg. Public-domain source-code is available at: http://crypto.stanford.edu/vpaes/ Benchmark on Intel Core2 T8100 (2.1Ghz, no turbo): Old: AES | nanosecs/byte mebibytes/sec cycles/byte ECB enc | 8.80 ns/B 108.4 MiB/s 18.48 c/B ECB dec | 9.07 ns/B 105.2 MiB/s 19.04 c/B CBC enc | 7.78 ns/B 122.7 MiB/s 16.33 c/B CBC dec | 7.71 ns/B 123.8 MiB/s 16.18 c/B CFB enc | 7.89 ns/B 120.9 MiB/s 16.56 c/B CFB dec | 7.56 ns/B 126.1 MiB/s 15.88 c/B OFB enc | 9.04 ns/B 105.5 MiB/s 18.99 c/B OFB dec | 9.01 ns/B 105.9 MiB/s 18.91 c/B CTR enc | 7.79 ns/B 122.3 MiB/s 16.37 c/B CTR dec | 7.94 ns/B 120.2 MiB/s 16.67 c/B New: AES | nanosecs/byte mebibytes/sec cycles/byte ECB enc | 5.92 ns/B 161.1 MiB/s 12.43 c/B ECB dec | 7.19 ns/B 132.6 MiB/s 15.11 c/B CBC enc | 5.30 ns/B 180.0 MiB/s 11.12 c/B CBC dec | 6.54 ns/B 145.9 MiB/s 13.73 c/B CFB enc | 5.22 ns/B 182.9 MiB/s 10.95 c/B CFB dec | 5.29 ns/B 180.2 MiB/s 11.11 c/B OFB enc | 6.20 ns/B 153.8 MiB/s 13.02 c/B OFB dec | 6.19 ns/B 154.2 MiB/s 12.99 c/B CTR enc | 5.30 ns/B 179.8 MiB/s 11.14 c/B CTR dec | 5.31 ns/B 179.7 MiB/s 11.14 c/B Signed-off-by: Jussi Kivilinna --- cipher/Makefile.am | 2 cipher/rijndael-internal.h | 9 cipher/rijndael-ssse3-amd64.c | 1219 +++++++++++++++++++++++++++++++++++++++++ cipher/rijndael.c | 96 +++ configure.ac | 3 5 files changed, 1326 insertions(+), 3 deletions(-) create mode 100644 cipher/rijndael-ssse3-amd64.c diff --git a/cipher/Makefile.am b/cipher/Makefile.am index 98142ed..7dd626c 100644 --- a/cipher/Makefile.am +++ b/cipher/Makefile.am @@ -75,7 +75,7 @@ md4.c \ md5.c \ poly1305-sse2-amd64.S poly1305-avx2-amd64.S poly1305-armv7-neon.S \ rijndael.c rijndael-internal.h rijndael-tables.h rijndael-aesni.c \ - rijndael-padlock.c rijndael-amd64.S rijndael-arm.S \ + rijndael-padlock.c rijndael-amd64.S rijndael-arm.S rijndael-ssse3-amd64.c \ rmd160.c \ rsa.c \ salsa20.c salsa20-amd64.S salsa20-armv7-neon.S \ diff --git a/cipher/rijndael-internal.h b/cipher/rijndael-internal.h index 7ff8660..854980b 100644 --- a/cipher/rijndael-internal.h +++ b/cipher/rijndael-internal.h @@ -43,6 +43,12 @@ # define USE_AMD64_ASM 1 #endif +/* USE_SSSE3 indicates whether to use SSSE3 code. */ +#if defined(__x86_64__) && defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) && \ + defined(HAVE_GCC_INLINE_ASM_SSSE3) +# define USE_SSSE3 1 +#endif + /* USE_ARM_ASM indicates whether to use ARM assembly code. */ #undef USE_ARM_ASM #if defined(__ARMEL__) @@ -116,6 +122,9 @@ typedef struct RIJNDAEL_context_s #ifdef USE_AESNI unsigned int use_aesni:1; /* AES-NI shall be used. */ #endif /*USE_AESNI*/ +#ifdef USE_SSSE3 + unsigned int use_ssse3:1; /* SSSE3 shall be used. */ +#endif /*USE_SSSE3*/ rijndael_cryptfn_t encrypt_fn; rijndael_cryptfn_t decrypt_fn; rijndael_prefetchfn_t prefetch_enc_fn; diff --git a/cipher/rijndael-ssse3-amd64.c b/cipher/rijndael-ssse3-amd64.c new file mode 100644 index 0000000..080e54e --- /dev/null +++ b/cipher/rijndael-ssse3-amd64.c @@ -0,0 +1,1219 @@ +/* SSSE3 vector permutation AES for Libgcrypt + * Copyright (C) 2014 Jussi Kivilinna + * + * This file is part of Libgcrypt. + * + * Libgcrypt is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * Libgcrypt is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, see . + */ + +#include +#include +#include +#include /* for memcmp() */ + +#include "types.h" /* for byte and u32 typedefs */ +#include "g10lib.h" +#include "cipher.h" +#include "bufhelp.h" +#include "cipher-selftest.h" +#include "rijndael-internal.h" + + +#ifdef USE_SSSE3 + + +/* Two macros to be called prior and after the use of SSSE3 + instructions. There should be no external function calls between + the use of these macros. There purpose is to make sure that the + SSE regsiters are cleared and won't reveal any information about + the key or the data. */ +#define vpaes_ssse3_prepare(const_ptr) do { \ + asm volatile ("call _aes_preheat\n\t" \ + "movq %%r10, %q0\n\t" \ + : "=c" (const_ptr) \ + : \ + : "r10", "memory", "cc" ); \ + } while (0) +#define vpaes_ssse3_cleanup() do { \ + asm volatile ("call _aes_cleanup\n\t" ::: "memory", "cc" ); \ + } while (0) + + +void +_gcry_aes_ssse3_do_setkey (RIJNDAEL_context *ctx, const byte *key) +{ + unsigned int keybits = (ctx->rounds - 10) * 32 + 128; + + asm volatile ("leaq %q[key], %%rdi" "\n\t" + "movl %[bits], %%esi" "\n\t" + "leaq %[buf], %%rdx" "\n\t" + "movl %[dir], %%ecx" "\n\t" + "movl %[rotoffs], %%r8d" "\n\t" + "call _aes_schedule_core" "\n\t" + : + : [key] "m" (*key), + [bits] "g" (keybits), + [buf] "m" (ctx->keyschenc32[0][0]), + [dir] "g" (0), + [rotoffs] "g" (48) + : "r8", "r9", "r10", "r11", "rax", "rcx", "rdx", "rdi", "rsi", + "cc", "memory"); + + /* Save key for setting up decryption. */ + memcpy(&ctx->keyschdec32[0][0], key, keybits / 8); +} + + +/* Make a decryption key from an encryption key. */ +void +_gcry_aes_ssse3_prepare_decryption (RIJNDAEL_context *ctx) +{ + unsigned int keybits = (ctx->rounds - 10) * 32 + 128; + + asm volatile ("leaq %q[key], %%rdi" "\n\t" + "movl %[bits], %%esi" "\n\t" + "leaq %[buf], %%rdx" "\n\t" + "movl %[dir], %%ecx" "\n\t" + "movl %[rotoffs], %%r8d" "\n\t" + "call _aes_schedule_core" "\n\t" + : + : [key] "m" (ctx->keyschdec32[0][0]), + [bits] "g" (keybits), + [buf] "m" (ctx->keyschdec32[ctx->rounds][0]), + [dir] "g" (1), + [rotoffs] "g" ((keybits == 192) ? 0 : 32) + : "r8", "r9", "r10", "r11", "rax", "rcx", "rdx", "rdi", "rsi", + "cc", "memory"); +} + + +/* Encrypt one block using the Intel SSSE3 instructions. Block is input + * and output through SSE register xmm0. */ +static inline void +do_vpaes_ssse3_enc (const RIJNDAEL_context *ctx, unsigned int nrounds, + const void *aes_const_ptr) +{ + unsigned int middle_rounds = nrounds - 1; + + asm volatile ("call _aes_encrypt_core" "\n\t" + : "+a" (middle_rounds) + : "d" (ctx->keyschenc32), "c" (aes_const_ptr) + : "r9", "r11", "cc"); +} + + +/* Decrypt one block using the Intel SSSE3 instructions. Block is input + * and output through SSE register xmm0. */ +static inline void +do_vpaes_ssse3_dec (const RIJNDAEL_context *ctx, unsigned int nrounds, + const void *aes_const_ptr) +{ + unsigned int middle_rounds = nrounds - 1; + + asm volatile ("call _aes_decrypt_core" "\n\t" + : "+a" (middle_rounds) + : "d" (ctx->keyschdec32), "c" (aes_const_ptr) + : "r9", "r11", "cc"); +} + + + +unsigned int +_gcry_aes_ssse3_encrypt (const RIJNDAEL_context *ctx, unsigned char *dst, + const unsigned char *src) +{ + unsigned int nrounds = ctx->rounds; + const void *aes_const_ptr; + + vpaes_ssse3_prepare (aes_const_ptr); + asm volatile ("movdqu %[src], %%xmm0\n\t" + : + : [src] "m" (*src) + : "memory" ); + do_vpaes_ssse3_enc (ctx, nrounds, aes_const_ptr); + asm volatile ("movdqu %%xmm0, %[dst]\n\t" + : [dst] "=m" (*dst) + : + : "memory" ); + vpaes_ssse3_cleanup (); + return 0; +} + + +void +_gcry_aes_ssse3_cfb_enc (RIJNDAEL_context *ctx, unsigned char *outbuf, + const unsigned char *inbuf, unsigned char *iv, + size_t nblocks) +{ + unsigned int nrounds = ctx->rounds; + const void *aes_const_ptr; + + vpaes_ssse3_prepare (aes_const_ptr); + + asm volatile ("movdqu %[iv], %%xmm0\n\t" + : /* No output */ + : [iv] "m" (*iv) + : "memory" ); + + for ( ;nblocks; nblocks-- ) + { + do_vpaes_ssse3_enc (ctx, nrounds, aes_const_ptr); + + asm volatile ("movdqu %[inbuf], %%xmm1\n\t" + "pxor %%xmm1, %%xmm0\n\t" + "movdqu %%xmm0, %[outbuf]\n\t" + : [outbuf] "=m" (*outbuf) + : [inbuf] "m" (*inbuf) + : "memory" ); + + outbuf += BLOCKSIZE; + inbuf += BLOCKSIZE; + } + + asm volatile ("movdqu %%xmm0, %[iv]\n\t" + : [iv] "=m" (*iv) + : + : "memory" ); + + vpaes_ssse3_cleanup (); +} + + +void +_gcry_aes_ssse3_cbc_enc (RIJNDAEL_context *ctx, unsigned char *outbuf, + const unsigned char *inbuf, unsigned char *iv, + size_t nblocks, int cbc_mac) +{ + unsigned int nrounds = ctx->rounds; + const void *aes_const_ptr; + + vpaes_ssse3_prepare (aes_const_ptr); + + asm volatile ("movdqu %[iv], %%xmm7\n\t" + : /* No output */ + : [iv] "m" (*iv) + : "memory" ); + + for ( ;nblocks; nblocks-- ) + { + asm volatile ("movdqu %[inbuf], %%xmm0\n\t" + "pxor %%xmm7, %%xmm0\n\t" + : /* No output */ + : [inbuf] "m" (*inbuf) + : "memory" ); + + do_vpaes_ssse3_enc (ctx, nrounds, aes_const_ptr); + + asm volatile ("movdqa %%xmm0, %%xmm7\n\t" + "movdqu %%xmm0, %[outbuf]\n\t" + : [outbuf] "=m" (*outbuf) + : + : "memory" ); + + inbuf += BLOCKSIZE; + if (!cbc_mac) + outbuf += BLOCKSIZE; + } + + asm volatile ("movdqu %%xmm7, %[iv]\n\t" + : [iv] "=m" (*iv) + : + : "memory" ); + + vpaes_ssse3_cleanup (); +} + + +void +_gcry_aes_ssse3_ctr_enc (RIJNDAEL_context *ctx, unsigned char *outbuf, + const unsigned char *inbuf, unsigned char *ctr, + size_t nblocks) +{ + unsigned int nrounds = ctx->rounds; + const void *aes_const_ptr; + 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 }; + + vpaes_ssse3_prepare (aes_const_ptr); + + asm volatile ("movdqa %[mask], %%xmm6\n\t" /* Preload mask */ + "movdqa %[ctr], %%xmm7\n\t" /* Preload CTR */ + : /* No output */ + : [mask] "m" (*be_mask), + [ctr] "m" (*ctr) + : "memory"); + + for ( ;nblocks; nblocks-- ) + { + asm volatile ("movdqa %%xmm7, %%xmm0\n\t" /* xmm0 := CTR (xmm7) */ + "pcmpeqd %%xmm1, %%xmm1\n\t" + "psrldq $8, %%xmm1\n\t" /* xmm1 = -1 */ + + "pshufb %%xmm6, %%xmm7\n\t" + "psubq %%xmm1, %%xmm7\n\t" /* xmm7++ (big endian) */ + + /* detect if 64-bit carry handling is needed */ + "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, %%xmm7\n\t" /* add carry to upper 64bits */ + + ".Lno_carry%=:\n\t" + + "pshufb %%xmm6, %%xmm7\n\t" + "movdqa %%xmm7, (%[ctr])\n\t" /* Update CTR (mem). */ + : + : [ctr] "r" (ctr) + : "cc", "memory"); + + do_vpaes_ssse3_enc (ctx, nrounds, aes_const_ptr); + + asm volatile ("movdqu %[src], %%xmm1\n\t" /* xmm1 := input */ + "pxor %%xmm1, %%xmm0\n\t" /* EncCTR ^= input */ + "movdqu %%xmm0, %[dst]" /* Store EncCTR. */ + : [dst] "=m" (*outbuf) + : [src] "m" (*inbuf) + : "memory"); + + outbuf += BLOCKSIZE; + inbuf += BLOCKSIZE; + } + + vpaes_ssse3_cleanup (); +} + + +unsigned int +_gcry_aes_ssse3_decrypt (const RIJNDAEL_context *ctx, unsigned char *dst, + const unsigned char *src) +{ + unsigned int nrounds = ctx->rounds; + const void *aes_const_ptr; + + vpaes_ssse3_prepare (aes_const_ptr); + asm volatile ("movdqu %[src], %%xmm0\n\t" + : + : [src] "m" (*src) + : "memory" ); + do_vpaes_ssse3_dec (ctx, nrounds, aes_const_ptr); + asm volatile ("movdqu %%xmm0, %[dst]\n\t" + : [dst] "=m" (*dst) + : + : "memory" ); + vpaes_ssse3_cleanup (); + return 0; +} + + +void +_gcry_aes_ssse3_cfb_dec (RIJNDAEL_context *ctx, unsigned char *outbuf, + const unsigned char *inbuf, unsigned char *iv, + size_t nblocks) +{ + unsigned int nrounds = ctx->rounds; + const void *aes_const_ptr; + + vpaes_ssse3_prepare (aes_const_ptr); + + asm volatile ("movdqu %[iv], %%xmm0\n\t" + : /* No output */ + : [iv] "m" (*iv) + : "memory" ); + + for ( ;nblocks; nblocks-- ) + { + do_vpaes_ssse3_enc (ctx, nrounds, aes_const_ptr); + + asm volatile ("movdqa %%xmm0, %%xmm6\n\t" + "movdqu %[inbuf], %%xmm0\n\t" + "pxor %%xmm0, %%xmm6\n\t" + "movdqu %%xmm6, %[outbuf]\n\t" + : [outbuf] "=m" (*outbuf) + : [inbuf] "m" (*inbuf) + : "memory" ); + + outbuf += BLOCKSIZE; + inbuf += BLOCKSIZE; + } + + asm volatile ("movdqu %%xmm0, %[iv]\n\t" + : [iv] "=m" (*iv) + : + : "memory" ); + + vpaes_ssse3_cleanup (); +} + + +void +_gcry_aes_ssse3_cbc_dec (RIJNDAEL_context *ctx, unsigned char *outbuf, + const unsigned char *inbuf, unsigned char *iv, + size_t nblocks) +{ + unsigned int nrounds = ctx->rounds; + const void *aes_const_ptr; + + vpaes_ssse3_prepare (aes_const_ptr); + + asm volatile + ("movdqu %[iv], %%xmm7\n\t" /* use xmm7 as fast IV storage */ + : /* No output */ + : [iv] "m" (*iv) + : "memory"); + + for ( ;nblocks; nblocks-- ) + { + asm volatile + ("movdqu %[inbuf], %%xmm0\n\t" + "movdqa %%xmm0, %%xmm6\n\t" /* use xmm6 as savebuf */ + : /* No output */ + : [inbuf] "m" (*inbuf) + : "memory"); + + do_vpaes_ssse3_dec (ctx, nrounds, aes_const_ptr); + + asm volatile + ("pxor %%xmm7, %%xmm0\n\t" /* xor IV with output */ + "movdqu %%xmm0, %[outbuf]\n\t" + "movdqu %%xmm6, %%xmm7\n\t" /* store savebuf as new IV */ + : [outbuf] "=m" (*outbuf) + : + : "memory"); + + outbuf += BLOCKSIZE; + inbuf += BLOCKSIZE; + } + + asm volatile + ("movdqu %%xmm7, %[iv]\n\t" /* store IV */ + : /* No output */ + : [iv] "m" (*iv) + : "memory"); + + vpaes_ssse3_cleanup (); +} + + + +asm ( + "\n\t" "##" + "\n\t" "## Constant-time SSSE3 AES core implementation." + "\n\t" "## version 0.1" + "\n\t" "##" + "\n\t" "## By Mike Hamburg (Stanford University), 2009" + "\n\t" "## Public domain." + "\n\t" "##" + + "\n\t" ".text" + + "\n\t" "##" + "\n\t" "## _aes_preheat" + "\n\t" "##" + "\n\t" "## Fills register %r10 -> .Laes_consts (so you can -fPIC)" + "\n\t" "## and %xmm8-%xmm15 as specified below." + "\n\t" "##" + "\n\t" ".align 16" + "\n\t" ".type _aes_preheat, at function" + "\n\t" "_aes_preheat:" + "\n\t" " lea .Laes_consts(%rip), %r10" + "\n\t" " movdqa (%r10), %xmm9 # 0F" + "\n\t" " movdqa .Lk_inv (%r10), %xmm10 # inv" + "\n\t" " movdqa .Lk_inv+16(%r10), %xmm11 # inva" + "\n\t" " movdqa .Lk_sb1 (%r10), %xmm13 # sb1u" + "\n\t" " movdqa .Lk_sb1+16(%r10), %xmm12 # sb1t" + "\n\t" " movdqa .Lk_sb2 (%r10), %xmm15 # sb2u" + "\n\t" " movdqa .Lk_sb2+16(%r10), %xmm14 # sb2t" + "\n\t" " ret" + "\n\t" ".size _aes_preheat,.-_aes_preheat" + + "\n\t" "##" + "\n\t" "## _aes_encrypt_core" + "\n\t" "##" + "\n\t" "## AES-encrypt %xmm0." + "\n\t" "##" + "\n\t" "## Inputs:" + "\n\t" "## %xmm0 = input" + "\n\t" "## %xmm9-%xmm15 as in .Laes_preheat" + "\n\t" "## %rcx = .Laes_consts" + "\n\t" "## (%rdx) = scheduled keys" + "\n\t" "## %rax = nrounds - 1" + "\n\t" "##" + "\n\t" "## Output in %xmm0" + "\n\t" "## Clobbers %xmm1-%xmm4, %r9, %r11, %rax" + "\n\t" "## Preserves %xmm5 - %xmm8 so you get some local vectors" + "\n\t" "##" + "\n\t" "##" + "\n\t" ".align 16" + "\n\t" ".type _aes_encrypt_core, at function" + "\n\t" "_aes_encrypt_core:" + "\n\t" " lea -16(%rdx), %r9" + "\n\t" " mov $16, %r11" + "\n\t" " movdqa .Lk_ipt (%rcx), %xmm2 # iptlo" + "\n\t" " movdqa %xmm9, %xmm1" + "\n\t" " pandn %xmm0, %xmm1" + "\n\t" " psrld $4, %xmm1" + "\n\t" " pand %xmm9, %xmm0" + "\n\t" " pshufb %xmm0, %xmm2" + "\n\t" " movdqa .Lk_ipt+16(%rcx), %xmm0 # ipthi" + "\n\t" " pshufb %xmm1, %xmm0" + "\n\t" " pxor 16(%r9),%xmm2" + "\n\t" " pxor %xmm2, %xmm0" + "\n\t" " add $32, %r9" + "\n\t" " jmp .Laes_entry" + + "\n\t" ".align 16" + "\n\t" ".Laes_loop:" + "\n\t" " # middle of middle round" + "\n\t" " movdqa %xmm13, %xmm4 # 4 : sb1u" + "\n\t" " pshufb %xmm2, %xmm4 # 4 = sb1u" + "\n\t" " pxor (%r9), %xmm4 # 4 = sb1u + k" + "\n\t" " movdqa %xmm12, %xmm0 # 0 : sb1t" + "\n\t" " pshufb %xmm3, %xmm0 # 0 = sb1t" + "\n\t" " pxor %xmm4, %xmm0 # 0 = A" + "\n\t" " movdqa %xmm15, %xmm4 # 4 : sb2u" + "\n\t" " pshufb %xmm2, %xmm4 # 4 = sb2u" + "\n\t" " movdqa .Lk_mc_forward(%r11,%rcx), %xmm1" + "\n\t" " movdqa %xmm14, %xmm2 # 2 : sb2t" + "\n\t" " pshufb %xmm3, %xmm2 # 2 = sb2t" + "\n\t" " pxor %xmm4, %xmm2 # 2 = 2A" + "\n\t" " movdqa %xmm0, %xmm3 # 3 = A" + "\n\t" " pshufb %xmm1, %xmm0 # 0 = B" + "\n\t" " pxor %xmm2, %xmm0 # 0 = 2A+B" + "\n\t" " pshufb .Lk_mc_backward(%r11,%rcx), %xmm3 # 3 = D" + "\n\t" " pxor %xmm0, %xmm3 # 3 = 2A+B+D" + "\n\t" " add $16, %r9 # next key" + "\n\t" " pshufb %xmm1, %xmm0 # 0 = 2B+C" + "\n\t" " pxor %xmm3, %xmm0 # 0 = 2A+3B+C+D" + "\n\t" " add $16, %r11 # next mc" + "\n\t" " and $48, %r11 # ... mod 4" + "\n\t" " dec %rax # nr--" + + "\n\t" ".Laes_entry:" + "\n\t" " # top of round" + "\n\t" " movdqa %xmm9, %xmm1 # 1 : i" + "\n\t" " pandn %xmm0, %xmm1 # 1 = i<<4" + "\n\t" " psrld $4, %xmm1 # 1 = i" + "\n\t" " pand %xmm9, %xmm0 # 0 = k" + "\n\t" " movaps %xmm11, %xmm2 # 2 : a/k" + "\n\t" " pshufb %xmm0, %xmm2 # 2 = a/k" + "\n\t" " pxor %xmm1, %xmm0 # 0 = j" + "\n\t" " movaps %xmm10, %xmm3 # 3 : 1/i" + "\n\t" " pshufb %xmm1, %xmm3 # 3 = 1/i" + "\n\t" " pxor %xmm2, %xmm3 # 3 = iak = 1/i + a/k" + "\n\t" " movaps %xmm10, %xmm4 # 4 : 1/j" + "\n\t" " pshufb %xmm0, %xmm4 # 4 = 1/j" + "\n\t" " pxor %xmm2, %xmm4 # 4 = jak = 1/j + a/k" + "\n\t" " movaps %xmm10, %xmm2 # 2 : 1/iak" + "\n\t" " pshufb %xmm3, %xmm2 # 2 = 1/iak" + "\n\t" " pxor %xmm0, %xmm2 # 2 = io" + "\n\t" " movaps %xmm10, %xmm3 # 3 : 1/jak" + "\n\t" " pshufb %xmm4, %xmm3 # 3 = 1/jak" + "\n\t" " pxor %xmm1, %xmm3 # 3 = jo" + "\n\t" " jnz .Laes_loop" + + "\n\t" " # middle of last round" + "\n\t" " movdqa .Lk_sbo(%rcx), %xmm4 # 3 : sbou" + "\n\t" " pshufb %xmm2, %xmm4 # 4 = sbou" + "\n\t" " pxor (%r9), %xmm4 # 4 = sb1u + k" + "\n\t" " movdqa .Lk_sbo+16(%rcx), %xmm0 # 0 : sbot" + "\n\t" " pshufb %xmm3, %xmm0 # 0 = sb1t" + "\n\t" " pxor %xmm4, %xmm0 # 0 = A" + "\n\t" " pshufb .Lk_sr(%r11,%rcx), %xmm0" + "\n\t" " ret" + "\n\t" ".size _aes_encrypt_core,.-_aes_encrypt_core" + + "\n\t" "##" + "\n\t" "## .Laes_cleanup" + "\n\t" "##" + "\n\t" "## Erases sensitive registers %xmm0-%xmm8" + "\n\t" "##" + "\n\t" ".align 16" + "\n\t" ".type _aes_cleanup, at function" + "\n\t" "_aes_cleanup:" + "\n\t" " pxor %xmm0, %xmm0" + "\n\t" " pxor %xmm1, %xmm1" + "\n\t" " pxor %xmm2, %xmm2" + "\n\t" " pxor %xmm3, %xmm3" + "\n\t" " pxor %xmm4, %xmm4" + "\n\t" " pxor %xmm5, %xmm5" + "\n\t" " pxor %xmm6, %xmm6" + "\n\t" " pxor %xmm7, %xmm7" + "\n\t" " pxor %xmm8, %xmm8" + "\n\t" " ret" + "\n\t" ".size _aes_cleanup,.-_aes_cleanup" + + "\n\t" "##" + "\n\t" "## Decryption core" + "\n\t" "##" + "\n\t" "## Same API as encryption core, except that it clobbers" + "\n\t" "## %xmm5. It's actually not clear that this is worthwhile." + "\n\t" "##" + "\n\t" ".align 16" + "\n\t" ".type _aes_decrypt_core, at function" + "\n\t" "_aes_decrypt_core:" + "\n\t" " lea -16(%rdx), %r9 # load key" + "\n\t" " mov %rax, %r11" + "\n\t" " shl $4, %r11" + "\n\t" " xor $48, %r11" + "\n\t" " and $48, %r11" + "\n\t" " movdqa .Lk_dipt (%rcx), %xmm2 # iptlo" + "\n\t" " movdqa %xmm9, %xmm1" + "\n\t" " pandn %xmm0, %xmm1" + "\n\t" " psrld $4, %xmm1" + "\n\t" " pand %xmm9, %xmm0" + "\n\t" " pshufb %xmm0, %xmm2" + "\n\t" " movdqa .Lk_dipt+16(%rcx), %xmm0 # ipthi" + "\n\t" " pshufb %xmm1, %xmm0" + "\n\t" " pxor 16(%r9),%xmm2" + "\n\t" " pxor %xmm2, %xmm0" + "\n\t" " add $32, %r9" + "\n\t" " movdqa .Lk_mc_forward+48(%rcx), %xmm5" + "\n\t" " jmp .Laes_dec_entry" + + "\n\t" ".align 16" + "\n\t" ".Laes_dec_loop:" + "\n\t" "##" + "\n\t" "## Inverse mix columns" + "\n\t" "##" + "\n\t" " movdqa (%r9), %xmm0" + "\n\t" " movdqa .Lk_dsb9(%rcx),%xmm4 # 4 : sb9u" + "\n\t" " pshufb %xmm2, %xmm4 # 4 = sb9u" + "\n\t" " pxor %xmm0, %xmm4" + "\n\t" " movdqa .Lk_dsb9+16(%rcx),%xmm0 # 0 : sb9t" + "\n\t" " pshufb %xmm3, %xmm0 # 0 = sb9t" + "\n\t" " pxor %xmm4, %xmm0 # 0 = ch" + "\n\t" " add $16, %r9 # next round key" + + "\n\t" " pshufb %xmm5, %xmm0 # MC ch" + "\n\t" " movdqa .Lk_dsbd(%rcx),%xmm4 # 4 : sbdu" + "\n\t" " pshufb %xmm2, %xmm4 # 4 = sbdu" + "\n\t" " pxor %xmm0, %xmm4 # 4 = ch" + "\n\t" " movdqa .Lk_dsbd+16(%rcx),%xmm0 # 0 : sbdt" + "\n\t" " pshufb %xmm3, %xmm0 # 0 = sbdt" + "\n\t" " pxor %xmm4, %xmm0 # 0 = ch" + "\n\t" " dec %rax # nr--" + + "\n\t" " pshufb %xmm5, %xmm0 # MC ch" + "\n\t" " movdqa .Lk_dsbb(%rcx),%xmm4 # 4 : sbbu" + "\n\t" " pshufb %xmm2, %xmm4 # 4 = sbbu" + "\n\t" " pxor %xmm0, %xmm4 # 4 = ch" + "\n\t" " movdqa .Lk_dsbb+16(%rcx),%xmm0 # 0 : sbbt" + "\n\t" " pshufb %xmm3, %xmm0 # 0 = sbbt" + "\n\t" " pxor %xmm4, %xmm0 # 0 = ch" + + "\n\t" " pshufb %xmm5, %xmm0 # MC ch" + "\n\t" " movdqa .Lk_dsbe(%rcx),%xmm4 # 4 : sbeu" + "\n\t" " pshufb %xmm2, %xmm4 # 4 = sbeu" + "\n\t" " pxor %xmm0, %xmm4 # 4 = ch" + "\n\t" " movdqa .Lk_dsbe+16(%rcx),%xmm0 # 0 : sbet" + "\n\t" " pshufb %xmm3, %xmm0 # 0 = sbet" + "\n\t" " pxor %xmm4, %xmm0 # 0 = ch" + + "\n\t" " palignr $12, %xmm5, %xmm5" + + "\n\t" ".Laes_dec_entry:" + "\n\t" " # top of round" + "\n\t" " movdqa %xmm9, %xmm1 # 1 : i" + "\n\t" " pandn %xmm0, %xmm1 # 1 = i<<4" + "\n\t" " psrld $4, %xmm1 # 1 = i" + "\n\t" " pand %xmm9, %xmm0 # 0 = k" + "\n\t" " movaps %xmm11, %xmm2 # 2 : a/k" + "\n\t" " pshufb %xmm0, %xmm2 # 2 = a/k" + "\n\t" " pxor %xmm1, %xmm0 # 0 = j" + "\n\t" " movaps %xmm10, %xmm3 # 3 : 1/i" + "\n\t" " pshufb %xmm1, %xmm3 # 3 = 1/i" + "\n\t" " pxor %xmm2, %xmm3 # 3 = iak = 1/i + a/k" + "\n\t" " movaps %xmm10, %xmm4 # 4 : 1/j" + "\n\t" " pshufb %xmm0, %xmm4 # 4 = 1/j" + "\n\t" " pxor %xmm2, %xmm4 # 4 = jak = 1/j + a/k" + "\n\t" " movaps %xmm10, %xmm2 # 2 : 1/iak" + "\n\t" " pshufb %xmm3, %xmm2 # 2 = 1/iak" + "\n\t" " pxor %xmm0, %xmm2 # 2 = io" + "\n\t" " movaps %xmm10, %xmm3 # 3 : 1/jak" + "\n\t" " pshufb %xmm4, %xmm3 # 3 = 1/jak" + "\n\t" " pxor %xmm1, %xmm3 # 3 = jo" + "\n\t" " jnz .Laes_dec_loop" + + "\n\t" " # middle of last round" + "\n\t" " movdqa .Lk_dsbo(%rcx), %xmm4 # 3 : sbou" + "\n\t" " pshufb %xmm2, %xmm4 # 4 = sbou" + "\n\t" " pxor (%r9), %xmm4 # 4 = sb1u + k" + "\n\t" " movdqa .Lk_dsbo+16(%rcx), %xmm0 # 0 : sbot" + "\n\t" " pshufb %xmm3, %xmm0 # 0 = sb1t" + "\n\t" " pxor %xmm4, %xmm0 # 0 = A" + "\n\t" " pshufb .Lk_sr(%r11,%rcx), %xmm0" + "\n\t" " ret" + "\n\t" ".size _aes_decrypt_core,.-_aes_decrypt_core" + + "\n\t" "########################################################" + "\n\t" "## ##" + "\n\t" "## AES key schedule ##" + "\n\t" "## ##" + "\n\t" "########################################################" + + "\n\t" ".align 16" + "\n\t" ".type _aes_schedule_core, at function" + "\n\t" "_aes_schedule_core:" + "\n\t" " # rdi = key" + "\n\t" " # rsi = size in bits" + "\n\t" " # rdx = buffer" + "\n\t" " # rcx = direction. 0=encrypt, 1=decrypt" + + "\n\t" " call _aes_preheat # load the tables" + "\n\t" " movdqa .Lk_rcon(%r10), %xmm8 # load rcon" + "\n\t" " movdqu (%rdi), %xmm0 # load key (unaligned)" + + "\n\t" " # input transform" + "\n\t" " movdqu %xmm0, %xmm3" + "\n\t" " lea .Lk_ipt(%r10), %r11" + "\n\t" " call .Laes_schedule_transform" + "\n\t" " movdqu %xmm0, %xmm7" + + "\n\t" " test %rcx, %rcx" + "\n\t" " jnz .Laes_schedule_am_decrypting" + + "\n\t" " # encrypting, output zeroth round key after transform" + "\n\t" " movdqa %xmm0, (%rdx)" + "\n\t" " jmp .Laes_schedule_go" + + "\n\t" ".Laes_schedule_am_decrypting:" + "\n\t" " # decrypting, output zeroth round key after shiftrows" + "\n\t" " pshufb .Lk_sr(%r8,%r10),%xmm3" + "\n\t" " movdqa %xmm3, (%rdx)" + "\n\t" " xor $48, %r8" + + "\n\t" ".Laes_schedule_go:" + "\n\t" " cmp $192, %rsi" + "\n\t" " je .Laes_schedule_192" + "\n\t" " cmp $256, %rsi" + "\n\t" " je .Laes_schedule_256" + "\n\t" " # 128: fall though" + + "\n\t" "##" + "\n\t" "## .Laes_schedule_128" + "\n\t" "##" + "\n\t" "## 128-bit specific part of key schedule." + "\n\t" "##" + "\n\t" "## This schedule is really simple, because all its parts" + "\n\t" "## are accomplished by the subroutines." + "\n\t" "##" + "\n\t" ".Laes_schedule_128:" + "\n\t" " mov $10, %rsi" + + "\n\t" ".Laes_schedule_128_L:" + "\n\t" " call .Laes_schedule_round" + "\n\t" " dec %rsi" + "\n\t" " jz .Laes_schedule_mangle_last" + "\n\t" " call .Laes_schedule_mangle # write output" + "\n\t" " jmp .Laes_schedule_128_L" + + "\n\t" "##" + "\n\t" "## .Laes_schedule_192" + "\n\t" "##" + "\n\t" "## 192-bit specific part of key schedule." + "\n\t" "##" + "\n\t" "## The main body of this schedule is the same as the 128-bit" + "\n\t" "## schedule, but with more smearing. The long, high side is" + "\n\t" "## stored in %xmm7 as before, and the short, low side is in" + "\n\t" "## the high bits of %xmm6." + "\n\t" "##" + "\n\t" "## This schedule is somewhat nastier, however, because each" + "\n\t" "## round produces 192 bits of key material, or 1.5 round keys." + "\n\t" "## Therefore, on each cycle we do 2 rounds and produce 3 round" + "\n\t" "## keys." + "\n\t" "##" + "\n\t" ".Laes_schedule_192:" + "\n\t" " movdqu 8(%rdi),%xmm0 # load key part 2 (very unaligned)" + "\n\t" " call .Laes_schedule_transform # input transform" + "\n\t" " movdqa %xmm0, %xmm6 # save short part" + "\n\t" " pxor %xmm4, %xmm4 # clear 4" + "\n\t" " movhlps %xmm4, %xmm6 # clobber low side with zeros" + "\n\t" " mov $4, %rsi" + + "\n\t" ".Laes_schedule_192_L:" + "\n\t" " call .Laes_schedule_round" + "\n\t" " palignr $8,%xmm6,%xmm0 " + "\n\t" " call .Laes_schedule_mangle # save key n" + "\n\t" " call .Laes_schedule_192_smear" + "\n\t" " call .Laes_schedule_mangle # save key n+1" + "\n\t" " call .Laes_schedule_round" + "\n\t" " dec %rsi" + "\n\t" " jz .Laes_schedule_mangle_last" + "\n\t" " call .Laes_schedule_mangle # save key n+2" + "\n\t" " call .Laes_schedule_192_smear" + "\n\t" " jmp .Laes_schedule_192_L" + + "\n\t" "##" + "\n\t" "## .Laes_schedule_192_smear" + "\n\t" "##" + "\n\t" "## Smear the short, low side in the 192-bit key schedule." + "\n\t" "##" + "\n\t" "## Inputs:" + "\n\t" "## %xmm7: high side, b a x y" + "\n\t" "## %xmm6: low side, d c 0 0" + "\n\t" "## %xmm13: 0" + "\n\t" "##" + "\n\t" "## Outputs:" + "\n\t" "## %xmm6: b+c+d b+c 0 0" + "\n\t" "## %xmm0: b+c+d b+c b a" + "\n\t" "##" + "\n\t" ".Laes_schedule_192_smear:" + "\n\t" " pshufd $0x80, %xmm6, %xmm0 # d c 0 0 -> c 0 0 0" + "\n\t" " pxor %xmm0, %xmm6 # -> c+d c 0 0" + "\n\t" " pshufd $0xFE, %xmm7, %xmm0 # b a _ _ -> b b b a" + "\n\t" " pxor %xmm0, %xmm6 # -> b+c+d b+c b a" + "\n\t" " movdqa %xmm6, %xmm0" + "\n\t" " pxor %xmm1, %xmm1" + "\n\t" " movhlps %xmm1, %xmm6 # clobber low side with zeros" + "\n\t" " ret" + + "\n\t" "##" + "\n\t" "## .Laes_schedule_256" + "\n\t" "##" + "\n\t" "## 256-bit specific part of key schedule." + "\n\t" "##" + "\n\t" "## The structure here is very similar to the 128-bit" + "\n\t" "## schedule, but with an additional 'low side' in" + "\n\t" "## %xmm6. The low side's rounds are the same as the" + "\n\t" "## high side's, except no rcon and no rotation." + "\n\t" "##" + "\n\t" ".Laes_schedule_256:" + "\n\t" " movdqu 16(%rdi),%xmm0 # load key part 2 (unaligned)" + "\n\t" " call .Laes_schedule_transform # input transform" + "\n\t" " mov $7, %rsi" + + "\n\t" ".Laes_schedule_256_L:" + "\n\t" " call .Laes_schedule_mangle # output low result" + "\n\t" " movdqa %xmm0, %xmm6 # save cur_lo in xmm6" + + "\n\t" " # high round" + "\n\t" " call .Laes_schedule_round" + "\n\t" " dec %rsi" + "\n\t" " jz .Laes_schedule_mangle_last" + "\n\t" " call .Laes_schedule_mangle " + + "\n\t" " # low round. swap xmm7 and xmm6" + "\n\t" " pshufd $0xFF, %xmm0, %xmm0" + "\n\t" " movdqa %xmm7, %xmm5" + "\n\t" " movdqa %xmm6, %xmm7" + "\n\t" " call .Laes_schedule_low_round" + "\n\t" " movdqa %xmm5, %xmm7" + + "\n\t" " jmp .Laes_schedule_256_L" + + "\n\t" "##" + "\n\t" "## .Laes_schedule_round" + "\n\t" "##" + "\n\t" "## Runs one main round of the key schedule on %xmm0, %xmm7" + "\n\t" "##" + "\n\t" "## Specifically, runs subbytes on the high dword of %xmm0" + "\n\t" "## then rotates it by one byte and xors into the low dword of" + "\n\t" "## %xmm7." + "\n\t" "##" + "\n\t" "## Adds rcon from low byte of %xmm8, then rotates %xmm8 for" + "\n\t" "## next rcon." + "\n\t" "##" + "\n\t" "## Smears the dwords of %xmm7 by xoring the low into the" + "\n\t" "## second low, result into third, result into highest." + "\n\t" "##" + "\n\t" "## Returns results in %xmm7 = %xmm0." + "\n\t" "## Clobbers %xmm1-%xmm4, %r11." + "\n\t" "##" + "\n\t" ".Laes_schedule_round:" + "\n\t" " # extract rcon from xmm8" + "\n\t" " pxor %xmm1, %xmm1" + "\n\t" " palignr $15, %xmm8, %xmm1" + "\n\t" " palignr $15, %xmm8, %xmm8" + "\n\t" " pxor %xmm1, %xmm7" + + "\n\t" " # rotate" + "\n\t" " pshufd $0xFF, %xmm0, %xmm0" + "\n\t" " palignr $1, %xmm0, %xmm0" + + "\n\t" " # fall through..." + + "\n\t" " # low round: same as high round, but no rotation and no rcon." + "\n\t" ".Laes_schedule_low_round:" + "\n\t" " # smear xmm7" + "\n\t" " movdqa %xmm7, %xmm1" + "\n\t" " pslldq $4, %xmm7" + "\n\t" " pxor %xmm1, %xmm7" + "\n\t" " movdqa %xmm7, %xmm1" + "\n\t" " pslldq $8, %xmm7" + "\n\t" " pxor %xmm1, %xmm7" + "\n\t" " pxor .Lk_s63(%r10), %xmm7" + + "\n\t" " # subbytes" + "\n\t" " movdqa %xmm9, %xmm1" + "\n\t" " pandn %xmm0, %xmm1" + "\n\t" " psrld $4, %xmm1 # 1 = i" + "\n\t" " pand %xmm9, %xmm0 # 0 = k" + "\n\t" " movaps %xmm11, %xmm2 # 2 : a/k" + "\n\t" " pshufb %xmm0, %xmm2 # 2 = a/k" + "\n\t" " pxor %xmm1, %xmm0 # 0 = j" + "\n\t" " movaps %xmm10, %xmm3 # 3 : 1/i" + "\n\t" " pshufb %xmm1, %xmm3 # 3 = 1/i" + "\n\t" " pxor %xmm2, %xmm3 # 3 = iak = 1/i + a/k" + "\n\t" " movaps %xmm10, %xmm4 # 4 : 1/j" + "\n\t" " pshufb %xmm0, %xmm4 # 4 = 1/j" + "\n\t" " pxor %xmm2, %xmm4 # 4 = jak = 1/j + a/k" + "\n\t" " movaps %xmm10, %xmm2 # 2 : 1/iak" + "\n\t" " pshufb %xmm3, %xmm2 # 2 = 1/iak" + "\n\t" " pxor %xmm0, %xmm2 # 2 = io" + "\n\t" " movaps %xmm10, %xmm3 # 3 : 1/jak" + "\n\t" " pshufb %xmm4, %xmm3 # 3 = 1/jak" + "\n\t" " pxor %xmm1, %xmm3 # 3 = jo" + "\n\t" " movdqa .Lk_sb1(%r10), %xmm4 # 4 : sbou" + "\n\t" " pshufb %xmm2, %xmm4 # 4 = sbou" + "\n\t" " movdqa .Lk_sb1+16(%r10), %xmm0 # 0 : sbot" + "\n\t" " pshufb %xmm3, %xmm0 # 0 = sb1t" + "\n\t" " pxor %xmm4, %xmm0 # 0 = sbox output" + + "\n\t" " # add in smeared stuff" + "\n\t" " pxor %xmm7, %xmm0 " + "\n\t" " movdqa %xmm0, %xmm7" + "\n\t" " ret" + + "\n\t" "##" + "\n\t" "## .Laes_schedule_transform" + "\n\t" "##" + "\n\t" "## Linear-transform %xmm0 according to tables at (%r11)" + "\n\t" "##" + "\n\t" "## Requires that %xmm9 = 0x0F0F... as in preheat" + "\n\t" "## Output in %xmm0" + "\n\t" "## Clobbers %xmm1, %xmm2" + "\n\t" "##" + "\n\t" ".Laes_schedule_transform:" + "\n\t" " movdqa %xmm9, %xmm1" + "\n\t" " pandn %xmm0, %xmm1" + "\n\t" " psrld $4, %xmm1" + "\n\t" " pand %xmm9, %xmm0" + "\n\t" " movaps (%r11), %xmm2 # lo" + "\n\t" " pshufb %xmm0, %xmm2" + "\n\t" " movaps 16(%r11), %xmm0 # hi" + "\n\t" " pshufb %xmm1, %xmm0" + "\n\t" " pxor %xmm2, %xmm0" + "\n\t" " ret" + + "\n\t" "##" + "\n\t" "## .Laes_schedule_mangle" + "\n\t" "##" + "\n\t" "## Mangle xmm0 from (basis-transformed) standard version" + "\n\t" "## to our version." + "\n\t" "##" + "\n\t" "## On encrypt," + "\n\t" "## xor with 0x63" + "\n\t" "## multiply by circulant 0,1,1,1" + "\n\t" "## apply shiftrows transform" + "\n\t" "##" + "\n\t" "## On decrypt," + "\n\t" "## xor with 0x63" + "\n\t" "## multiply by 'inverse mixcolumns' circulant E,B,D,9" + "\n\t" "## deskew" + "\n\t" "## apply shiftrows transform" + "\n\t" "##" + "\n\t" "##" + "\n\t" "## Writes out to (%rdx), and increments or decrements it" + "\n\t" "## Keeps track of round number mod 4 in %r8" + "\n\t" "## Preserves xmm0" + "\n\t" "## Clobbers xmm1-xmm5" + "\n\t" "##" + "\n\t" ".Laes_schedule_mangle:" + "\n\t" " movdqa %xmm0, %xmm4 # save xmm0 for later" + "\n\t" " movdqa .Lk_mc_forward(%r10),%xmm5" + "\n\t" " test %rcx, %rcx" + "\n\t" " jnz .Laes_schedule_mangle_dec" + + "\n\t" " # encrypting" + "\n\t" " add $16, %rdx" + "\n\t" " pxor .Lk_s63(%r10),%xmm4" + "\n\t" " pshufb %xmm5, %xmm4" + "\n\t" " movdqa %xmm4, %xmm3" + "\n\t" " pshufb %xmm5, %xmm4" + "\n\t" " pxor %xmm4, %xmm3" + "\n\t" " pshufb %xmm5, %xmm4" + "\n\t" " pxor %xmm4, %xmm3" + + "\n\t" " jmp .Laes_schedule_mangle_both" + + "\n\t" ".Laes_schedule_mangle_dec:" + "\n\t" " lea .Lk_dks_1(%r10), %r11 # first table: *9" + "\n\t" " call .Laes_schedule_transform" + "\n\t" " movdqa %xmm0, %xmm3" + "\n\t" " pshufb %xmm5, %xmm3" + + "\n\t" " add $32, %r11 # next table: *B" + "\n\t" " call .Laes_schedule_transform" + "\n\t" " pxor %xmm0, %xmm3" + "\n\t" " pshufb %xmm5, %xmm3" + + "\n\t" " add $32, %r11 # next table: *D" + "\n\t" " call .Laes_schedule_transform" + "\n\t" " pxor %xmm0, %xmm3" + "\n\t" " pshufb %xmm5, %xmm3" + + "\n\t" " add $32, %r11 # next table: *E" + "\n\t" " call .Laes_schedule_transform" + "\n\t" " pxor %xmm0, %xmm3" + "\n\t" " pshufb %xmm5, %xmm3" + + "\n\t" " movdqa %xmm4, %xmm0 # restore %xmm0" + "\n\t" " add $-16, %rdx" + + "\n\t" ".Laes_schedule_mangle_both:" + "\n\t" " pshufb .Lk_sr(%r8,%r10),%xmm3" + "\n\t" " add $-16, %r8" + "\n\t" " and $48, %r8" + "\n\t" " movdqa %xmm3, (%rdx)" + "\n\t" " ret" + + "\n\t" "##" + "\n\t" "## .Laes_schedule_mangle_last" + "\n\t" "##" + "\n\t" "## Mangler for last round of key schedule" + "\n\t" "## Mangles %xmm0" + "\n\t" "## when encrypting, outputs out(%xmm0) ^ 63" + "\n\t" "## when decrypting, outputs unskew(%xmm0)" + "\n\t" "##" + "\n\t" "## Always called right before return... jumps to cleanup and exits" + "\n\t" "##" + "\n\t" ".Laes_schedule_mangle_last:" + "\n\t" " # schedule last round key from xmm0" + "\n\t" " lea .Lk_deskew(%r10),%r11 # prepare to deskew" + "\n\t" " test %rcx, %rcx" + "\n\t" " jnz .Laes_schedule_mangle_last_dec" + + "\n\t" " # encrypting" + "\n\t" " pshufb .Lk_sr(%r8,%r10),%xmm0 # output permute" + "\n\t" " lea .Lk_opt(%r10), %r11 # prepare to output transform" + "\n\t" " add $32, %rdx" + + "\n\t" ".Laes_schedule_mangle_last_dec:" + "\n\t" " add $-16, %rdx" + "\n\t" " pxor .Lk_s63(%r10), %xmm0" + "\n\t" " call .Laes_schedule_transform # output transform" + "\n\t" " movdqa %xmm0, (%rdx) # save last key" + "\n\t" " jmp _aes_cleanup" + "\n\t" ".size _aes_schedule_core,.-_aes_schedule_core" + + "\n\t" "########################################################" + "\n\t" "## ##" + "\n\t" "## Constants ##" + "\n\t" "## ##" + "\n\t" "########################################################" + + "\n\t" ".align 16" + "\n\t" ".type _aes_consts, at object" + "\n\t" ".Laes_consts:" + "\n\t" "_aes_consts:" + "\n\t" " # s0F" + "\n\t" " .Lk_s0F = .-.Laes_consts" + "\n\t" " .quad 0x0F0F0F0F0F0F0F0F" + "\n\t" " .quad 0x0F0F0F0F0F0F0F0F" + + "\n\t" " # input transform (lo, hi)" + "\n\t" " .Lk_ipt = .-.Laes_consts" + "\n\t" " .quad 0xC2B2E8985A2A7000" + "\n\t" " .quad 0xCABAE09052227808" + "\n\t" " .quad 0x4C01307D317C4D00" + "\n\t" " .quad 0xCD80B1FCB0FDCC81" + + "\n\t" " # inv, inva" + "\n\t" " .Lk_inv = .-.Laes_consts" + "\n\t" " .quad 0x0E05060F0D080180" + "\n\t" " .quad 0x040703090A0B0C02" + "\n\t" " .quad 0x01040A060F0B0780" + "\n\t" " .quad 0x030D0E0C02050809" + + "\n\t" " # sb1u, sb1t" + "\n\t" " .Lk_sb1 = .-.Laes_consts" + "\n\t" " .quad 0xB19BE18FCB503E00" + "\n\t" " .quad 0xA5DF7A6E142AF544" + "\n\t" " .quad 0x3618D415FAE22300" + "\n\t" " .quad 0x3BF7CCC10D2ED9EF" + + + "\n\t" " # sb2u, sb2t" + "\n\t" " .Lk_sb2 = .-.Laes_consts" + "\n\t" " .quad 0xE27A93C60B712400" + "\n\t" " .quad 0x5EB7E955BC982FCD" + "\n\t" " .quad 0x69EB88400AE12900" + "\n\t" " .quad 0xC2A163C8AB82234A" + + "\n\t" " # sbou, sbot" + "\n\t" " .Lk_sbo = .-.Laes_consts" + "\n\t" " .quad 0xD0D26D176FBDC700" + "\n\t" " .quad 0x15AABF7AC502A878" + "\n\t" " .quad 0xCFE474A55FBB6A00" + "\n\t" " .quad 0x8E1E90D1412B35FA" + + "\n\t" " # mc_forward" + "\n\t" " .Lk_mc_forward = .-.Laes_consts" + "\n\t" " .quad 0x0407060500030201" + "\n\t" " .quad 0x0C0F0E0D080B0A09" + "\n\t" " .quad 0x080B0A0904070605" + "\n\t" " .quad 0x000302010C0F0E0D" + "\n\t" " .quad 0x0C0F0E0D080B0A09" + "\n\t" " .quad 0x0407060500030201" + "\n\t" " .quad 0x000302010C0F0E0D" + "\n\t" " .quad 0x080B0A0904070605" + + "\n\t" " # mc_backward" + "\n\t" " .Lk_mc_backward = .-.Laes_consts" + "\n\t" " .quad 0x0605040702010003" + "\n\t" " .quad 0x0E0D0C0F0A09080B" + "\n\t" " .quad 0x020100030E0D0C0F" + "\n\t" " .quad 0x0A09080B06050407" + "\n\t" " .quad 0x0E0D0C0F0A09080B" + "\n\t" " .quad 0x0605040702010003" + "\n\t" " .quad 0x0A09080B06050407" + "\n\t" " .quad 0x020100030E0D0C0F" + + "\n\t" " # sr" + "\n\t" " .Lk_sr = .-.Laes_consts" + "\n\t" " .quad 0x0706050403020100" + "\n\t" " .quad 0x0F0E0D0C0B0A0908" + "\n\t" " .quad 0x030E09040F0A0500" + "\n\t" " .quad 0x0B06010C07020D08" + "\n\t" " .quad 0x0F060D040B020900" + "\n\t" " .quad 0x070E050C030A0108" + "\n\t" " .quad 0x0B0E0104070A0D00" + "\n\t" " .quad 0x0306090C0F020508" + + "\n\t" " # rcon" + "\n\t" " .Lk_rcon = .-.Laes_consts" + "\n\t" " .quad 0x1F8391B9AF9DEEB6" + "\n\t" " .quad 0x702A98084D7C7D81" + + "\n\t" " # s63: all equal to 0x63 transformed" + "\n\t" " .Lk_s63 = .-.Laes_consts" + "\n\t" " .quad 0x5B5B5B5B5B5B5B5B" + "\n\t" " .quad 0x5B5B5B5B5B5B5B5B" + + "\n\t" " # output transform" + "\n\t" " .Lk_opt = .-.Laes_consts" + "\n\t" " .quad 0xFF9F4929D6B66000" + "\n\t" " .quad 0xF7974121DEBE6808" + "\n\t" " .quad 0x01EDBD5150BCEC00" + "\n\t" " .quad 0xE10D5DB1B05C0CE0" + + "\n\t" " # deskew tables: inverts the sbox's 'skew'" + "\n\t" " .Lk_deskew = .-.Laes_consts" + "\n\t" " .quad 0x07E4A34047A4E300" + "\n\t" " .quad 0x1DFEB95A5DBEF91A" + "\n\t" " .quad 0x5F36B5DC83EA6900" + "\n\t" " .quad 0x2841C2ABF49D1E77" + + "\n\t" "##" + "\n\t" "## Decryption stuff" + "\n\t" "## Key schedule constants" + "\n\t" "##" + "\n\t" " # decryption key schedule: x -> invskew x*9" + "\n\t" " .Lk_dks_1 = .-.Laes_consts" + "\n\t" " .quad 0xB6116FC87ED9A700" + "\n\t" " .quad 0x4AED933482255BFC" + "\n\t" " .quad 0x4576516227143300" + "\n\t" " .quad 0x8BB89FACE9DAFDCE" + + "\n\t" " # decryption key schedule: invskew x*9 -> invskew x*D" + "\n\t" " .Lk_dks_2 = .-.Laes_consts" + "\n\t" " .quad 0x27438FEBCCA86400" + "\n\t" " .quad 0x4622EE8AADC90561" + "\n\t" " .quad 0x815C13CE4F92DD00" + "\n\t" " .quad 0x73AEE13CBD602FF2" + + "\n\t" " # decryption key schedule: invskew x*D -> invskew x*B" + "\n\t" " .Lk_dks_3 = .-.Laes_consts" + "\n\t" " .quad 0x03C4C50201C6C700" + "\n\t" " .quad 0xF83F3EF9FA3D3CFB" + "\n\t" " .quad 0xEE1921D638CFF700" + "\n\t" " .quad 0xA5526A9D7384BC4B" + + "\n\t" " # decryption key schedule: invskew x*B -> invskew x*E + 0x63" + "\n\t" " .Lk_dks_4 = .-.Laes_consts" + "\n\t" " .quad 0xE3C390B053732000" + "\n\t" " .quad 0xA080D3F310306343" + "\n\t" " .quad 0xA0CA214B036982E8" + "\n\t" " .quad 0x2F45AEC48CE60D67" + + "\n\t" "##" + "\n\t" "## Decryption stuff" + "\n\t" "## Round function constants" + "\n\t" "##" + "\n\t" " # decryption input transform" + "\n\t" " .Lk_dipt = .-.Laes_consts" + "\n\t" " .quad 0x0F505B040B545F00" + "\n\t" " .quad 0x154A411E114E451A" + "\n\t" " .quad 0x86E383E660056500" + "\n\t" " .quad 0x12771772F491F194" + + "\n\t" " # decryption sbox output *9*u, *9*t" + "\n\t" " .Lk_dsb9 = .-.Laes_consts" + "\n\t" " .quad 0x851C03539A86D600" + "\n\t" " .quad 0xCAD51F504F994CC9" + "\n\t" " .quad 0xC03B1789ECD74900" + "\n\t" " .quad 0x725E2C9EB2FBA565" + + "\n\t" " # decryption sbox output *D*u, *D*t" + "\n\t" " .Lk_dsbd = .-.Laes_consts" + "\n\t" " .quad 0x7D57CCDFE6B1A200" + "\n\t" " .quad 0xF56E9B13882A4439" + "\n\t" " .quad 0x3CE2FAF724C6CB00" + "\n\t" " .quad 0x2931180D15DEEFD3" + + "\n\t" " # decryption sbox output *B*u, *B*t" + "\n\t" " .Lk_dsbb = .-.Laes_consts" + "\n\t" " .quad 0xD022649296B44200" + "\n\t" " .quad 0x602646F6B0F2D404" + "\n\t" " .quad 0xC19498A6CD596700" + "\n\t" " .quad 0xF3FF0C3E3255AA6B" + + "\n\t" " # decryption sbox output *E*u, *E*t" + "\n\t" " .Lk_dsbe = .-.Laes_consts" + "\n\t" " .quad 0x46F2929626D4D000" + "\n\t" " .quad 0x2242600464B4F6B0" + "\n\t" " .quad 0x0C55A6CDFFAAC100" + "\n\t" " .quad 0x9467F36B98593E32" + + "\n\t" " # decryption sbox final output" + "\n\t" " .Lk_dsbo = .-.Laes_consts" + "\n\t" " .quad 0x1387EA537EF94000" + "\n\t" " .quad 0xC7AA6DB9D4943E2D" + "\n\t" " .quad 0x12D7560F93441D00" + "\n\t" " .quad 0xCA4B8159D8C58E9C" + + "\n\t" " .Lk_ctr_mask = .-.Laes_consts" + "\n\t" " .quad 0x0000000000000000" + "\n\t" " .quad 0xFFFFFFFFFFFFFFFF" + + "\n\t" " .Lk_ctr_one = .-.Laes_consts" + "\n\t" " .quad 0x0000000000000001" + "\n\t" " .quad 0x0000000000000000" + + "\n\t" " # ocb mode" + "\n\t" " .Lk_ocb_mask = .-.Laes_consts" + "\n\t" " .quad 0x0100000001000000" + "\n\t" " .quad 0x8680000001000000" + + "\n\t" " # padding" + "\n\t" " .Lk_reverse_id = .-.Laes_consts" + "\n\t" " .quad 0x08090A0B0C0D0E0F" + "\n\t" " .quad 0x0001020304050607" + "\n\t" ".size _aes_consts,.-_aes_consts" +); + +#endif /* USE_SSSE3 */ diff --git a/cipher/rijndael.c b/cipher/rijndael.c index 7a83718..51c36c7 100644 --- a/cipher/rijndael.c +++ b/cipher/rijndael.c @@ -99,6 +99,40 @@ extern void _gcry_aes_aesni_cbc_dec (RIJNDAEL_context *ctx, unsigned char *iv, size_t nblocks); #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 (RIJNDAEL_context *ctx, + unsigned char *outbuf, + const unsigned char *inbuf, + unsigned char *iv, size_t nblocks); +extern void _gcry_aes_ssse3_cbc_enc (RIJNDAEL_context *ctx, + unsigned char *outbuf, + const unsigned char *inbuf, + unsigned char *iv, size_t nblocks, + int cbc_mac); +extern void _gcry_aes_ssse3_ctr_enc (RIJNDAEL_context *ctx, + unsigned char *outbuf, + const unsigned char *inbuf, + unsigned char *ctr, size_t nblocks); +extern void _gcry_aes_ssse3_cfb_dec (RIJNDAEL_context *ctx, + unsigned char *outbuf, + const unsigned char *inbuf, + unsigned char *iv, size_t nblocks); +extern void _gcry_aes_ssse3_cbc_dec (RIJNDAEL_context *ctx, + unsigned char *outbuf, + const unsigned char *inbuf, + unsigned char *iv, size_t nblocks); +#endif + #ifdef USE_PADLOCK extern unsigned int _gcry_aes_padlock_encrypt (const RIJNDAEL_context *ctx, unsigned char *bx, @@ -182,7 +216,7 @@ do_setkey (RIJNDAEL_context *ctx, const byte *key, const unsigned keylen) int rounds; int i,j, r, t, rconpointer = 0; int KC; -#if defined(USE_AESNI) || defined(USE_PADLOCK) +#if defined(USE_AESNI) || defined(USE_PADLOCK) || defined(USE_SSSE3) unsigned int hwfeatures; #endif @@ -223,7 +257,7 @@ do_setkey (RIJNDAEL_context *ctx, const byte *key, const unsigned keylen) ctx->rounds = rounds; -#if defined(USE_AESNI) || defined(USE_PADLOCK) +#if defined(USE_AESNI) || defined(USE_PADLOCK) || defined(USE_SSSE3) hwfeatures = _gcry_get_hw_features (); #endif @@ -234,6 +268,9 @@ do_setkey (RIJNDAEL_context *ctx, const byte *key, const unsigned keylen) #ifdef USE_AESNI ctx->use_aesni = 0; #endif +#ifdef USE_SSSE3 + ctx->use_ssse3 = 0; +#endif if (0) { @@ -260,6 +297,16 @@ do_setkey (RIJNDAEL_context *ctx, const byte *key, const unsigned keylen) memcpy (ctx->padlockkey, key, keylen); } #endif +#ifdef USE_SSSE3 + else if (hwfeatures & HWF_INTEL_SSSE3) + { + ctx->encrypt_fn = _gcry_aes_ssse3_encrypt; + ctx->decrypt_fn = _gcry_aes_ssse3_decrypt; + ctx->prefetch_enc_fn = NULL; + ctx->prefetch_dec_fn = NULL; + ctx->use_ssse3 = 1; + } +#endif else { ctx->encrypt_fn = do_encrypt; @@ -278,6 +325,10 @@ do_setkey (RIJNDAEL_context *ctx, const byte *key, const unsigned keylen) else if (ctx->use_aesni) _gcry_aes_aesni_do_setkey (ctx, key); #endif +#ifdef USE_AESNI + else if (ctx->use_ssse3) + _gcry_aes_ssse3_do_setkey (ctx, key); +#endif else { const byte *sbox = ((const byte *)encT) + 1; @@ -403,6 +454,12 @@ prepare_decryption( RIJNDAEL_context *ctx ) _gcry_aes_aesni_prepare_decryption (ctx); } #endif /*USE_AESNI*/ +#ifdef USE_SSSE3 + else if (ctx->use_ssse3) + { + _gcry_aes_ssse3_prepare_decryption (ctx); + } +#endif /*USE_SSSE3*/ #ifdef USE_PADLOCK else if (ctx->use_padlock) { @@ -650,6 +707,13 @@ _gcry_aes_cfb_enc (void *context, unsigned char *iv, burn_depth = 0; } #endif /*USE_AESNI*/ +#ifdef USE_SSSE3 + else if (ctx->use_ssse3) + { + _gcry_aes_ssse3_cfb_enc (ctx, outbuf, inbuf, iv, nblocks); + burn_depth = 0; + } +#endif /*USE_SSSE3*/ else { rijndael_cryptfn_t encrypt_fn = ctx->encrypt_fn; @@ -697,6 +761,13 @@ _gcry_aes_cbc_enc (void *context, unsigned char *iv, burn_depth = 0; } #endif /*USE_AESNI*/ +#ifdef USE_SSSE3 + else if (ctx->use_ssse3) + { + _gcry_aes_ssse3_cbc_enc (ctx, outbuf, inbuf, iv, nblocks, cbc_mac); + burn_depth = 0; + } +#endif /*USE_SSSE3*/ else { rijndael_cryptfn_t encrypt_fn = ctx->encrypt_fn; @@ -752,6 +823,13 @@ _gcry_aes_ctr_enc (void *context, unsigned char *ctr, burn_depth = 0; } #endif /*USE_AESNI*/ +#ifdef USE_SSSE3 + else if (ctx->use_ssse3) + { + _gcry_aes_ssse3_ctr_enc (ctx, outbuf, inbuf, ctr, nblocks); + burn_depth = 0; + } +#endif /*USE_SSSE3*/ else { union { unsigned char x1[16] ATTR_ALIGNED_16; u32 x32[4]; } tmp; @@ -986,6 +1064,13 @@ _gcry_aes_cfb_dec (void *context, unsigned char *iv, burn_depth = 0; } #endif /*USE_AESNI*/ +#ifdef USE_SSSE3 + else if (ctx->use_ssse3) + { + _gcry_aes_ssse3_cfb_dec (ctx, outbuf, inbuf, iv, nblocks); + burn_depth = 0; + } +#endif /*USE_SSSE3*/ else { rijndael_cryptfn_t encrypt_fn = ctx->encrypt_fn; @@ -1032,6 +1117,13 @@ _gcry_aes_cbc_dec (void *context, unsigned char *iv, burn_depth = 0; } #endif /*USE_AESNI*/ +#ifdef USE_SSSE3 + else if (ctx->use_ssse3) + { + _gcry_aes_ssse3_cbc_dec (ctx, outbuf, inbuf, iv, nblocks); + burn_depth = 0; + } +#endif /*USE_SSSE3*/ else { unsigned char savebuf[BLOCKSIZE] ATTR_ALIGNED_16; diff --git a/configure.ac b/configure.ac index a4ea990..71c50c0 100644 --- a/configure.ac +++ b/configure.ac @@ -1692,6 +1692,9 @@ if test "$found" = "1" ; then x86_64-*-*) # Build with the assembly implementation GCRYPT_CIPHERS="$GCRYPT_CIPHERS rijndael-amd64.lo" + + # Build with the SSSE3 implementation + GCRYPT_CIPHERS="$GCRYPT_CIPHERS rijndael-ssse3-amd64.lo" ;; arm*-*-*) # Build with the assembly implementation