diff options
author | unknown <monty@hundin.mysql.fi> | 2002-06-19 00:22:30 +0300 |
---|---|---|
committer | unknown <monty@hundin.mysql.fi> | 2002-06-19 00:22:30 +0300 |
commit | 518787c29965d10f65a7e9c073718076aceb058c (patch) | |
tree | df0fd78ddd1c83d577e830a40da77487a62451b7 | |
parent | 9424f80f19a84eb667c3d588d8c0d19b833c7c28 (diff) | |
download | mariadb-git-518787c29965d10f65a7e9c073718076aceb058c.tar.gz |
Made keyread (key scanning) a key specific attribute.
This avoids using fulltext keys for table scanning.
This also reverts Sinisa's original fix for this problem.
Docs/manual.texi:
Update of SQL_JOIN_MAX_SIZE information3602
client/mysqldump.c:
comment cleanup
include/my_aes.h:
General cleanup for new file
include/rijndael.h:
General cleanup for new file
include/sha1.h:
General cleanup for new file
mysys/my_aes.c:
General cleanup for new file
mysys/rijndael.c:
General cleanup for new file
mysys/sha1.c:
General cleanup for new file
sql/ha_berkeley.h:
Made keyread (key scanning) a key specific attribute.
sql/ha_innodb.cc:
Merge with 3.23.x
sql/ha_innodb.h:
Made keyread (key scanning) a key specific attribute.
sql/ha_isam.cc:
Moved things to table_flags()
sql/ha_isam.h:
Made keyread (key scanning) a key specific attribute.
sql/ha_myisam.cc:
Made keyread (key scanning) a key specific attribute.
sql/ha_myisam.h:
Made keyread (key scanning) a key specific attribute.
sql/ha_myisammrg.h:
Made keyread (key scanning) a key specific attribute.
sql/handler.h:
Made keyread (key scanning) a key specific attribute.
sql/item_strfunc.cc:
Cleanup of AES_xxx code
sql/opt_range.cc:
Made keyread (key scanning) a key specific attribute.
sql/sql_base.cc:
Made keyread (key scanning) a key specific attribute.
sql/sql_cache.cc:
Removed compiler warning
sql/sql_select.cc:
Removed wrong patch to fulltext problem
sql/table.cc:
Made keyread (key scanning) a key specific attribute.
sql/table.h:
Made keyread (key scanning) a key specific attribute.
-rw-r--r-- | Docs/manual.texi | 6 | ||||
-rw-r--r-- | client/mysqldump.c | 4 | ||||
-rw-r--r-- | include/my_aes.h | 80 | ||||
-rw-r--r-- | include/rijndael.h | 50 | ||||
-rw-r--r-- | include/sha1.h | 75 | ||||
-rw-r--r-- | mysys/my_aes.c | 220 | ||||
-rw-r--r-- | mysys/rijndael.c | 1068 | ||||
-rw-r--r-- | mysys/sha1.c | 394 | ||||
-rw-r--r-- | sql/ha_berkeley.h | 3 | ||||
-rw-r--r-- | sql/ha_innodb.cc | 3 | ||||
-rw-r--r-- | sql/ha_innodb.h | 3 | ||||
-rw-r--r-- | sql/ha_isam.cc | 2 | ||||
-rw-r--r-- | sql/ha_isam.h | 18 | ||||
-rw-r--r-- | sql/ha_myisam.cc | 3 | ||||
-rw-r--r-- | sql/ha_myisam.h | 7 | ||||
-rw-r--r-- | sql/ha_myisammrg.h | 9 | ||||
-rw-r--r-- | sql/handler.h | 4 | ||||
-rw-r--r-- | sql/item_strfunc.cc | 31 | ||||
-rw-r--r-- | sql/opt_range.cc | 24 | ||||
-rw-r--r-- | sql/sql_base.cc | 16 | ||||
-rw-r--r-- | sql/sql_cache.cc | 4 | ||||
-rw-r--r-- | sql/sql_select.cc | 9 | ||||
-rw-r--r-- | sql/table.cc | 18 | ||||
-rw-r--r-- | sql/table.h | 4 |
24 files changed, 971 insertions, 1084 deletions
diff --git a/Docs/manual.texi b/Docs/manual.texi index d3f5995124e..32e1b431834 100644 --- a/Docs/manual.texi +++ b/Docs/manual.texi @@ -27645,6 +27645,12 @@ flag again, the @code{SQL_MAX_JOIN_SIZE} variable will be ignored. You can set a default value for this variable by starting @code{mysqld} with @code{-O max_join_size=#}. +Note that if the result of the query is in the query cache, the above +check will not be made, but MySQL will instead send the result to the +client. We regard this as a feature as in this case the query result is +already computed and it will not cause any big burden for the server to +send the result to the client. + @item SQL_QUERY_CACHE_TYPE = OFF | ON | DEMAND @item SQL_QUERY_CACHE_TYPE = 0 | 1 | 2 Set query cache setting for this thread. diff --git a/client/mysqldump.c b/client/mysqldump.c index 0ebf0727a58..54bfbef004b 100644 --- a/client/mysqldump.c +++ b/client/mysqldump.c @@ -1438,8 +1438,8 @@ int main(int argc, char **argv) else if (opt_single_transaction) /* Just to make it beautiful enough */ { /* - In case we were locking all tables, we did not start transaction - so there is no need to commit it. + In case we were locking all tables, we did not start transaction + so there is no need to commit it. */ /* This should just free locks as we did not change anything */ diff --git a/include/my_aes.h b/include/my_aes.h index 48ee11d15e5..5852baa5892 100644 --- a/include/my_aes.h +++ b/include/my_aes.h @@ -4,81 +4,63 @@ it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - - + + /* Header file for my_aes.c */ /* Wrapper to give simple interface for MySQL to AES standard encryption */ -#ifndef __MY_AES_H -#define __MY_AES_H - -#include "my_global.h" -#include <stdio.h> #include "rijndael.h" -#define AES_KEY_LENGTH 128 -/* Must be 128 192 or 256 */ +C_MODE_START -#ifdef __cplusplus -extern "C" { -#endif +#define AES_KEY_LENGTH 128 /* Must be 128 192 or 256 */ /* -my_aes_encrypt - Crypt buffer with AES encryption algorithm. -source - Pinter to data for encryption -source_length - size of encruption data -dest - buffer to place encrypted data (must be large enough) -key - Key to be used for encryption -kel_length - Lenght of the key. Will handle keys of any length - -returns - size of encrypted data, or negative in case of error. - + my_aes_encrypt - Crypt buffer with AES encryption algorithm. + source - Pointer to data for encryption + source_length - size of encryption data + dest - buffer to place encrypted data (must be large enough) + key - Key to be used for encryption + kel_length - Length of the key. Will handle keys of any length + + returns - size of encrypted data, or negative in case of error. */ -int my_aes_encrypt(const char* source, int source_length, const char* dest, - const char* key, int key_length); +int my_aes_encrypt(const char *source, int source_length, char *dest, + const char *key, int key_length); /* -my_aes_decrypt - DeCrypt buffer with AES encryption algorithm. -source - Pinter to data for decryption -source_length - size of encrypted data -dest - buffer to place decrypted data (must be large enough) -key - Key to be used for decryption -kel_length - Lenght of the key. Will handle keys of any length - -returns - size of original data, or negative in case of error. - + my_aes_decrypt - DeCrypt buffer with AES encryption algorithm. + source - Pointer to data for decryption + source_length - size of encrypted data + dest - buffer to place decrypted data (must be large enough) + key - Key to be used for decryption + kel_length - Length of the key. Will handle keys of any length + + returns - size of original data, or negative in case of error. */ -int my_aes_decrypt(const char* source, int source_length, const char* dest, - const char* key, int key_length); - +int my_aes_decrypt(const char *source, int source_length, char *dest, + const char *key, int key_length); /* -my_aes_get_size - get size of buffer which will be large enough for encrypted - data -source_length - length of data to be encrypted - -returns - size of buffer required to store encrypted data + my_aes_get_size - get size of buffer which will be large enough for encrypted + data + source_length - length of data to be encrypted + returns - size of buffer required to store encrypted data */ int my_aes_get_size(int source_length); - -#ifdef __cplusplus - } -#endif - - -#endif +C_MODE_END diff --git a/include/rijndael.h b/include/rijndael.h index 9d9f11e74bd..e286c89cbdc 100644 --- a/include/rijndael.h +++ b/include/rijndael.h @@ -4,45 +4,39 @@ it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - - + + /* - rijndael-alg-fst.h - - @version 3.0 (December 2000) - Optimised ANSI C code for the Rijndael cipher (now AES) - @author Vincent Rijmen <vincent.rijmen@esat.kuleuven.ac.be> - @author Antoon Bosselaers <antoon.bosselaers@esat.kuleuven.ac.be> - @author Paulo Barreto <paulo.barreto@terra.com.br> - - This code is hereby placed in the public domain. - - Modified by Peter Zaitsev to fit MySQL coding style. - + rijndael-alg-fst.h + + @version 3.0 (December 2000) + Optimised ANSI C code for the Rijndael cipher (now AES) + @author Vincent Rijmen <vincent.rijmen@esat.kuleuven.ac.be> + @author Antoon Bosselaers <antoon.bosselaers@esat.kuleuven.ac.be> + @author Paulo Barreto <paulo.barreto@terra.com.br> + + This code is hereby placed in the public domain. + Modified by Peter Zaitsev to fit MySQL coding style. */ -#ifndef __RIJNDAEL_ALG_FST_H -#define __RIJNDAEL_ALG_FST_H -#define MAXKC (256/32) -#define MAXKB (256/8) -#define MAXNR 14 +#define AES_MAXKC (256/32) +#define AES_MAXKB (256/8) +#define AES_MAXNR 14 -int rijndaelKeySetupEnc(uint32 rk[/*4*(Nr + 1)*/], const uint8 cipherKey[], - int keyBits); +int rijndaelKeySetupEnc(uint32 rk[/*4*(Nr + 1)*/], const uint8 cipherKey[], + int keyBits); int rijndaelKeySetupDec(uint32 rk[/*4*(Nr + 1)*/], const uint8 cipherKey[], - int keyBits); + int keyBits); void rijndaelEncrypt(const uint32 rk[/*4*(Nr + 1)*/], int Nr, - const uint8 pt[16], uint8 ct[16]); + const uint8 pt[16], uint8 ct[16]); void rijndaelDecrypt(const uint32 rk[/*4*(Nr + 1)*/], int Nr, - const uint8 ct[16], uint8 pt[16]); - -#endif /* __RIJNDAEL_ALG_FST_H */ + const uint8 ct[16], uint8 pt[16]); diff --git a/include/sha1.h b/include/sha1.h index 9871282cdd4..1c345469d3c 100644 --- a/include/sha1.h +++ b/include/sha1.h @@ -4,81 +4,64 @@ it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - + /* - sha1.h - - Description: - This is the header file for code which implements the Secure - Hashing Algorithm 1 as defined in FIPS PUB 180-1 published - April 17, 1995. - - Many of the variable names in this code, especially the - single character names, were used because those were the names - used in the publication. - - Please read the file sha1.c for more information. - -*/ - -/* Modified 2002 by Peter Zaitsev to better follow MySQL standards */ + This is the header file for code which implements the Secure + Hashing Algorithm 1 as defined in FIPS PUB 180-1 published + April 17, 1995. + Many of the variable names in this code, especially the + single character names, were used because those were the names + used in the publication. -#ifndef _SHA1_H_ -#define _SHA1_H_ + Please read the file sha1.c for more information. -#include "my_global.h" + Modified 2002 by Peter Zaitsev to better follow MySQL standards +*/ -/* Required for uint32, uint8, int16 ulonglong types */ enum sha_result_codes { - SHA_SUCCESS = 0, - SHA_NULL, /* Null pointer parameter */ - SHA_INPUT_TOO_LONG, /* input data too long */ - SHA_STATE_ERROR /* called Input after Result */ + SHA_SUCCESS = 0, + SHA_NULL, /* Null pointer parameter */ + SHA_INPUT_TOO_LONG, /* input data too long */ + SHA_STATE_ERROR /* called Input after Result */ }; #define SHA1_HASH_SIZE 20 /* Hash size in bytes */ /* - This structure will hold context information for the SHA-1 - hashing operation - */ + This structure will hold context information for the SHA-1 + hashing operation +*/ + typedef struct SHA1_CONTEXT { - ulonglong Length; /* Message length in bits */ + ulonglong Length; /* Message length in bits */ uint32 Intermediate_Hash[SHA1_HASH_SIZE/4]; /* Message Digest */ - int Computed; /* Is the digest computed? */ - int Corrupted; /* Is the message digest corrupted? */ - int16 Message_Block_Index; /* Index into message block array */ - uint8 Message_Block[64]; /* 512-bit message blocks */ + int Computed; /* Is the digest computed? */ + int Corrupted; /* Is the message digest corrupted? */ + int16 Message_Block_Index; /* Index into message block array */ + uint8 Message_Block[64]; /* 512-bit message blocks */ } SHA1_CONTEXT; /* - * Function Prototypes - */ - + Function Prototypes +*/ -#ifdef __cplusplus -extern "C" { -#endif +C_MODE_START int sha1_reset( SHA1_CONTEXT* ); int sha1_input( SHA1_CONTEXT*, const uint8 *, unsigned int ); int sha1_result( SHA1_CONTEXT* , uint8 Message_Digest[SHA1_HASH_SIZE] ); - -#ifdef __cplusplus -} -#endif -#endif +C_MODE_END diff --git a/mysys/my_aes.c b/mysys/my_aes.c index e1c538ef29c..b67166f8367 100644 --- a/mysys/my_aes.c +++ b/mysys/my_aes.c @@ -4,184 +4,196 @@ it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -/* - Implementation of AES Encryption for MySQL - Initial version by Peter Zaitsev June 2002 -*/ +/* + Implementation of AES Encryption for MySQL + Initial version by Peter Zaitsev June 2002 +*/ -#include "my_global.h" -#include "m_string.h" +#include <my_global.h> +#include <m_string.h> #include "my_aes.h" - enum encrypt_dir { AES_ENCRYPT, AES_DECRYPT }; -#define AES_BLOCK_SIZE 16 - /* Block size in bytes */ - -#define AES_BAD_DATA -1 - /* If bad data discovered during decoding */ - +#define AES_BLOCK_SIZE 16 /* Block size in bytes */ -/* The structure for key information */ +#define AES_BAD_DATA -1 /* If bad data discovered during decoding */ + + +/* The structure for key information */ typedef struct { - int nr; /* Number of rounds */ - uint32 rk[4*(MAXNR + 1)]; /* key schedule */ + int nr; /* Number of rounds */ + uint32 rk[4*(AES_MAXNR + 1)]; /* key schedule */ } KEYINSTANCE; - /* - This is internal function just keeps joint code of Key generation - rkey - Address of Key Instance to be created - direction - Direction (are we encoding or decoding) - key - key to use for real key creation - key_length - length of the key - - returns - returns 0 on success and negative on error - */ -static int my_aes_create_key(KEYINSTANCE* aes_key,char direction, char* key, - int key_length) -{ - char rkey[AES_KEY_LENGTH/8]; /* The real key to be used for encryption */ - char *ptr; /* Start of the real key*/ +/* + This is internal function just keeps joint code of Key generation + + SYNOPSIS + my_aes_create_key() + aes_key Address of Key Instance to be created + direction Direction (are we encoding or decoding) + key Key to use for real key creation + key_length Length of the key + + DESCRIPTION + + RESULT + 0 ok + -1 Error Note: The current impementation never returns this +*/ + +static int my_aes_create_key(KEYINSTANCE *aes_key, + enum encrypt_dir direction, const char *key, + int key_length) +{ + char rkey[AES_KEY_LENGTH/8]; /* The real key to be used for encryption */ char *rkey_end=rkey+AES_KEY_LENGTH/8; /* Real key boundary */ - char *sptr; /* Start of the working key */ - char *key_end=key+key_length; /* Working key boundary*/ - + char *ptr; /* Start of the real key*/ + const char *sptr; /* Start of the working key */ + const char *key_end=key+key_length; /* Working key boundary*/ + bzero(rkey,AES_KEY_LENGTH/8); /* Set initial key */ - + for (ptr= rkey, sptr= key; sptr < key_end; ptr++,sptr++) { if (ptr == rkey_end) ptr= rkey; /* Just loop over tmp_key until we used all key */ - *ptr^= *sptr; + *ptr^= *sptr; } - if (direction==AES_DECRYPT) + if (direction == AES_DECRYPT) aes_key->nr = rijndaelKeySetupDec(aes_key->rk, rkey, AES_KEY_LENGTH); - else + else aes_key->nr = rijndaelKeySetupEnc(aes_key->rk, rkey, AES_KEY_LENGTH); - return 0; + return 0; } /* -my_aes_encrypt - Crypt buffer with AES encryption algorithm. -source - Pinter to data for encryption -source_length - size of encruption data -dest - buffer to place encrypted data (must be large enough) -key - Key to be used for encryption -kel_length - Lenght of the key. Will handle keys of any length - -returns - size of encrypted data, or negative in case of error. - + Crypt buffer with AES encryption algorithm. + + SYNOPSIS + my_aes_encrypt() + source Pointer to data for encryption + source_length Size of encryption data + dest Buffer to place encrypted data (must be large enough) + key Key to be used for encryption + key_length Length of the key. Will handle keys of any length + + RETURN + >= 0 Size of encrypted data + < 0 Error */ -int my_aes_encrypt(const char* source, int source_length, const char* dest, - const char* key, int key_length) +int my_aes_encrypt(const char* source, int source_length, char* dest, + const char* key, int key_length) { KEYINSTANCE aes_key; - char block[AES_BLOCK_SIZE]; /* 128 bit block used for padding */ - int rc; /* result codes */ - int num_blocks; /* number of complete blocks */ - char pad_len; /* pad size for the last block */ + char block[AES_BLOCK_SIZE]; /* 128 bit block used for padding */ + int rc; /* result codes */ + int num_blocks; /* number of complete blocks */ + char pad_len; /* pad size for the last block */ int i; - - if ((rc=my_aes_create_key(&aes_key,AES_ENCRYPT,key,key_length))) + + if ((rc= my_aes_create_key(&aes_key,AES_ENCRYPT,key,key_length))) return rc; - - num_blocks = source_length/AES_BLOCK_SIZE; - + + num_blocks = source_length/AES_BLOCK_SIZE; + for (i = num_blocks; i > 0; i--) /* Encode complete blocks */ { rijndaelEncrypt(aes_key.rk, aes_key.nr, source, dest); source+= AES_BLOCK_SIZE; dest+= AES_BLOCK_SIZE; } - + /* Encode the rest. We always have incomplete block */ - pad_len = AES_BLOCK_SIZE - (source_length - AES_BLOCK_SIZE*num_blocks); - memcpy(block, source, 16 - pad_len); + pad_len = AES_BLOCK_SIZE - (source_length - AES_BLOCK_SIZE*num_blocks); + memcpy(block, source, 16 - pad_len); bfill(block + AES_BLOCK_SIZE - pad_len, pad_len, pad_len); rijndaelEncrypt(aes_key.rk, aes_key.nr, block, dest); - return AES_BLOCK_SIZE*(num_blocks + 1); + return AES_BLOCK_SIZE*(num_blocks + 1); } /* -my_aes_decrypt - DeCrypt buffer with AES encryption algorithm. -source - Pinter to data for decryption -source_length - size of encrypted data -dest - buffer to place decrypted data (must be large enough) -key - Key to be used for decryption -kel_length - Lenght of the key. Will handle keys of any length - -returns - size of original data, or negative in case of error. - -*/ + DeCrypt buffer with AES encryption algorithm. + + SYNOPSIS + my_aes_decrypt() + source Pointer to data for decryption + source_length Size of encrypted data + dest Buffer to place decrypted data (must be large enough) + key Key to be used for decryption + key_length Length of the key. Will handle keys of any length + + RETURN + >= 0 Size of encrypted data + < 0 Error +*/ -int my_aes_decrypt(const char* source, int source_length, const char* dest, - const char* key, int key_length) +int my_aes_decrypt(const char *source, int source_length, char *dest, + const char *key, int key_length) { KEYINSTANCE aes_key; - char block[AES_BLOCK_SIZE]; /* 128 bit block used for padding */ - int rc; /* result codes */ - int num_blocks; /* number of complete blocks */ - char pad_len; /* pad size for the last block */ + char block[AES_BLOCK_SIZE]; /* 128 bit block used for padding */ + int rc; /* Result codes */ + int num_blocks; /* Number of complete blocks */ + char pad_len; /* Pad size for the last block */ int i; - + if ((rc=my_aes_create_key(&aes_key,AES_DECRYPT,key,key_length))) return rc; - - num_blocks = source_length/AES_BLOCK_SIZE; - - - if ( (source_length!=num_blocks*AES_BLOCK_SIZE) || num_blocks==0) - return AES_BAD_DATA; /* Input size has to be even and at leas one block */ - - + + num_blocks = source_length/AES_BLOCK_SIZE; + + if ((source_length != num_blocks*AES_BLOCK_SIZE) || num_blocks ==0 ) + return AES_BAD_DATA; /* Input size has to be even and at least one block */ + for (i = num_blocks-1; i > 0; i--) /* Decode all but last blocks */ { rijndaelDecrypt(aes_key.rk, aes_key.nr, source, dest); source+= AES_BLOCK_SIZE; dest+= AES_BLOCK_SIZE; } - + rijndaelDecrypt(aes_key.rk, aes_key.nr, source, block); - pad_len = block[AES_BLOCK_SIZE-1]; /* Just use last char in the block as size*/ + pad_len = block[AES_BLOCK_SIZE-1]; /* Use last char in the block as size */ - if (pad_len > AES_BLOCK_SIZE) + if (pad_len > AES_BLOCK_SIZE) return AES_BAD_DATA; /* We could also check whole padding but we do not really need this */ - + memcpy(dest, block, AES_BLOCK_SIZE - pad_len); - - return AES_BLOCK_SIZE*num_blocks - pad_len; + return AES_BLOCK_SIZE*num_blocks - pad_len; } /* -my_aes_get_size - get size of buffer which will be large enough for encrypted - data -source_length - length of data to be encrypted -returns - size of buffer required to store encrypted data + Get size of buffer which will be large enough for encrypted data + + SYNOPSIS + my_aes_get_size() + source_length Length of data to be encrypted + + RETURN + Size of buffer required to store encrypted data */ - + int my_aes_get_size(int source_length) -{ +{ return AES_BLOCK_SIZE*(source_length/AES_BLOCK_SIZE)+AES_BLOCK_SIZE; } - - - diff --git a/mysys/rijndael.c b/mysys/rijndael.c index 4d53beb44cb..dd0c45445d5 100644 --- a/mysys/rijndael.c +++ b/mysys/rijndael.c @@ -4,46 +4,38 @@ it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or at your option) any later version. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - + /* - rijndael-alg-fst.c - - @version 3.0 (December 2000) - + Based on version 3.0 (December 2000) + Optimised ANSI C code for the Rijndael cipher (now AES) - - @author Vincent Rijmen <vincent.rijmen@esat.kuleuven.ac.be> - @author Antoon Bosselaers <antoon.bosselaers@esat.kuleuven.ac.be> - @author Paulo Barreto <paulo.barreto@terra.com.br> - - This code is hereby placed in the public domain. - - */ - -#include <my_global.h> -#include <assert.h>
+ author Vincent Rijmen <vincent.rijmen@esat.kuleuven.ac.be> + author Antoon Bosselaers <antoon.bosselaers@esat.kuleuven.ac.be> + author Paulo Barreto <paulo.barreto@terra.com.br> +*/ + +#include <my_global.h> +#include <assert.h> #include "rijndael.h" -/* - May be defined to use fastest and much larger code (~10K extra code) - #define FULL_UNROLL +/* + Define the following to use fastest and much larger code (~10K extra code) + #define FULL_UNROLL */ #ifdef NOT_USED - -/* Te0[x] = S [x].[02, 01, 01, 03]; Te1[x] = S [x].[03, 02, 01, 01]; Te2[x] = S [x].[01, 03, 02, 01]; @@ -55,10 +47,9 @@ Td1[x] = Si[x].[0b, 0e, 09, 0d]; Td2[x] = Si[x].[0d, 0b, 0e, 09]; Td3[x] = Si[x].[09, 0d, 0b, 0e]; Td4[x] = Si[x].[01, 01, 01, 01]; -*/ - #endif + static const uint32 Te0[256]= { 0xc66363a5U, 0xf87c7c84U, 0xee777799U, 0xf67b7b8dU, @@ -126,6 +117,7 @@ static const uint32 Te0[256]= 0x824141c3U, 0x299999b0U, 0x5a2d2d77U, 0x1e0f0f11U, 0x7bb0b0cbU, 0xa85454fcU, 0x6dbbbbd6U, 0x2c16163aU, }; + static const uint32 Te1[256]= { 0xa5c66363U, 0x84f87c7cU, 0x99ee7777U, 0x8df67b7bU, @@ -194,7 +186,8 @@ static const uint32 Te1[256]= 0xcb7bb0b0U, 0xfca85454U, 0xd66dbbbbU, 0x3a2c1616U, }; -static const uint32 Te2[256] = { +static const uint32 Te2[256]= +{ 0x63a5c663U, 0x7c84f87cU, 0x7799ee77U, 0x7b8df67bU, 0xf20dfff2U, 0x6bbdd66bU, 0x6fb1de6fU, 0xc55491c5U, 0x30506030U, 0x01030201U, 0x67a9ce67U, 0x2b7d562bU, @@ -738,85 +731,86 @@ static const uint32 Td4[256]= 0x55555555U, 0x21212121U, 0x0c0c0c0cU, 0x7d7d7d7dU, }; + /* for 128-bit blocks, Rijndael never uses more than 10 rcon values */ static const uint32 rcon[]= { 0x01000000, 0x02000000, 0x04000000, 0x08000000, 0x10000000, 0x20000000, 0x40000000, 0x80000000, - 0x1B000000, 0x36000000, + 0x1B000000, 0x36000000, }; -#define RJ_SWAP(x) (_lrotl(x, 8) & 0x00ff00ff | _lrotr(x, 8) & 0xff00ff00) - -#ifdef _MSC_VER +#if defined(_MSC_VER) && defined(__i386__) +#define RJ_SWAP(x) (_lrotl(x, 8) & 0x00ff00ff | _lrotr(x, 8) & 0xff00ff00) #define GETuint32(p) RJ_SWAP(*((uint32 *)(p))) #define PUTuint32(ct, st) { *((uint32 *)(ct)) = RJ_SWAP((st)); } #else #define GETuint32(pt) (((uint32)(pt)[0] << 24) ^ ((uint32)(pt)[1] << 16)\ - ^ ((uint32)(pt)[2] << 8) ^ ((uint32)(pt)[3])) + ^ ((uint32)(pt)[2] << 8) ^ ((uint32)(pt)[3])) #define PUTuint32(ct, st) { (ct)[0] = (uint8)((st) >> 24); (ct)[1]\ = (uint8)((st) >> 16); (ct)[2] = (uint8)((st) >> 8); (ct)[3] = (uint8)(st); } -#endif +#endif /* defined(_MSC_VER) && defined(__i386__) */ /* - Expand the cipher key into the encryption key schedule. - - @return the number of rounds for the given cipher key size. + Expand the cipher key into the encryption key schedule. + + RETURN + The number of rounds for the given cipher key size. */ -int rijndaelKeySetupEnc(uint32 rk[/*4*(Nr + 1)*/], const uint8 cipherKey[], - int keyBits) +int rijndaelKeySetupEnc(uint32 rk[/*4*(Nr + 1)*/], const uint8 cipherKey[], + int keyBits) { int i = 0; uint32 temp; - - rk[0] = GETuint32(cipherKey ); + + rk[0] = GETuint32(cipherKey ); rk[1] = GETuint32(cipherKey + 4); rk[2] = GETuint32(cipherKey + 8); rk[3] = GETuint32(cipherKey + 12); if (keyBits == 128) { - for (;;) + for (;;) { temp = rk[3]; - rk[4] = rk[0] ^ - (Te4[(temp >> 16) & 0xff] & 0xff000000) ^ - (Te4[(temp >> 8) & 0xff] & 0x00ff0000) ^ - (Te4[(temp ) & 0xff] & 0x0000ff00) ^ - (Te4[(temp >> 24) ] & 0x000000ff) ^ - rcon[i]; + rk[4] = (rk[0] ^ + (Te4[(temp >> 16) & 0xff] & 0xff000000) ^ + (Te4[(temp >> 8) & 0xff] & 0x00ff0000) ^ + (Te4[(temp ) & 0xff] & 0x0000ff00) ^ + (Te4[(temp >> 24) ] & 0x000000ff) ^ + rcon[i]); rk[5] = rk[1] ^ rk[4]; rk[6] = rk[2] ^ rk[5]; rk[7] = rk[3] ^ rk[6]; - if (++i == 10) - return 10; + if (++i == 10) + return 10; rk += 4; } } rk[4] = GETuint32(cipherKey + 16); rk[5] = GETuint32(cipherKey + 20); - if (keyBits == 192) + if (keyBits == 192) { - for (;;) + for (;;) { temp = rk[ 5]; rk[ 6] = (rk[ 0] ^ - (Te4[(temp >> 16) & 0xff] & 0xff000000) ^ - (Te4[(temp >> 8) & 0xff] & 0x00ff0000) ^ - (Te4[(temp ) & 0xff] & 0x0000ff00) ^ - (Te4[(temp >> 24) ] & 0x000000ff) ^ - rcon[i]); + (Te4[(temp >> 16) & 0xff] & 0xff000000) ^ + (Te4[(temp >> 8) & 0xff] & 0x00ff0000) ^ + (Te4[(temp ) & 0xff] & 0x0000ff00) ^ + (Te4[(temp >> 24) ] & 0x000000ff) ^ + rcon[i]); rk[ 7] = rk[ 1] ^ rk[ 6]; rk[ 8] = rk[ 2] ^ rk[ 7]; rk[ 9] = rk[ 3] ^ rk[ 8]; - if (++i == 8) + if (++i == 8) { - return 12; + return 12; } rk[10] = rk[ 4] ^ rk[ 9]; rk[11] = rk[ 5] ^ rk[10]; @@ -825,30 +819,30 @@ int rijndaelKeySetupEnc(uint32 rk[/*4*(Nr + 1)*/], const uint8 cipherKey[], } rk[6] = GETuint32(cipherKey + 24); rk[7] = GETuint32(cipherKey + 28); - if (keyBits == 256) + if (keyBits == 256) { - for (;;) + for (;;) { temp = rk[ 7]; rk[ 8] = (rk[ 0] ^ - (Te4[(temp >> 16) & 0xff] & 0xff000000) ^ - (Te4[(temp >> 8) & 0xff] & 0x00ff0000) ^ - (Te4[(temp ) & 0xff] & 0x0000ff00) ^ - (Te4[(temp >> 24) ] & 0x000000ff) ^ - rcon[i]); + (Te4[(temp >> 16) & 0xff] & 0xff000000) ^ + (Te4[(temp >> 8) & 0xff] & 0x00ff0000) ^ + (Te4[(temp ) & 0xff] & 0x0000ff00) ^ + (Te4[(temp >> 24) ] & 0x000000ff) ^ + rcon[i]); rk[ 9] = rk[ 1] ^ rk[ 8]; rk[10] = rk[ 2] ^ rk[ 9]; rk[11] = rk[ 3] ^ rk[10]; - if (++i == 7) + if (++i == 7) { - return 14; + return 14; } temp = rk[11]; rk[12] = (rk[ 4] ^ - (Te4[(temp >> 24) ] & 0xff000000) ^ - (Te4[(temp >> 16) & 0xff] & 0x00ff0000) ^ - (Te4[(temp >> 8) & 0xff] & 0x0000ff00) ^ - (Te4[(temp ) & 0xff] & 0x000000ff)); + (Te4[(temp >> 24) ] & 0xff000000) ^ + (Te4[(temp >> 16) & 0xff] & 0x00ff0000) ^ + (Te4[(temp >> 8) & 0xff] & 0x0000ff00) ^ + (Te4[(temp ) & 0xff] & 0x000000ff)); rk[13] = rk[ 5] ^ rk[12]; rk[14] = rk[ 6] ^ rk[13]; rk[15] = rk[ 7] ^ rk[14]; @@ -860,584 +854,544 @@ int rijndaelKeySetupEnc(uint32 rk[/*4*(Nr + 1)*/], const uint8 cipherKey[], /* -Expand the cipher key into the decryption key schedule. + Expand the cipher key into the decryption key schedule. -@return the number of rounds for the given cipher key size. + RETURN + The number of rounds for the given cipher key size. */ int rijndaelKeySetupDec(uint32 rk[/*4*(Nr + 1)*/], const uint8 cipherKey[], - int keyBits) + int keyBits) { - int Nr, i, j; + int nr, i, j; uint32 temp; - + /* expand the cipher key: */ - Nr = rijndaelKeySetupEnc(rk, cipherKey, keyBits); + nr = rijndaelKeySetupEnc(rk, cipherKey, keyBits); /* invert the order of the round keys: */ - for (i = 0, j = 4*Nr; i < j; i += 4, j -= 4) + for (i = 0, j = 4*nr; i < j; i += 4, j -= 4) { - temp = rk[i ]; rk[i ] = rk[j ]; rk[j ] = temp; + temp = rk[i ]; rk[i ] = rk[j ]; rk[j ] = temp; temp = rk[i + 1]; rk[i + 1] = rk[j + 1]; rk[j + 1] = temp; temp = rk[i + 2]; rk[i + 2] = rk[j + 2]; rk[j + 2] = temp; temp = rk[i + 3]; rk[i + 3] = rk[j + 3]; rk[j + 3] = temp; } - /* - apply the inverse MixColumn transform to - all round keys but the first and the last: + /* + Apply the inverse MixColumn transform to all round keys but the first + and the last: */ - for (i = 1; i < Nr; i++) + for (i = 1; i < nr; i++) { rk += 4; - - rk[0] = - Td0[Te4[(rk[0] >> 24) ] & 0xff] ^ - Td1[Te4[(rk[0] >> 16) & 0xff] & 0xff] ^ - Td2[Te4[(rk[0] >> 8) & 0xff] & 0xff] ^ - Td3[Te4[(rk[0] ) & 0xff] & 0xff]; - - rk[1] = - Td0[Te4[(rk[1] >> 24) ] & 0xff] ^ - Td1[Te4[(rk[1] >> 16) & 0xff] & 0xff] ^ - Td2[Te4[(rk[1] >> 8) & 0xff] & 0xff] ^ - Td3[Te4[(rk[1] ) & 0xff] & 0xff]; - - rk[2] = - Td0[Te4[(rk[2] >> 24) ] & 0xff] ^ - Td1[Te4[(rk[2] >> 16) & 0xff] & 0xff] ^ - Td2[Te4[(rk[2] >> 8) & 0xff] & 0xff] ^ - Td3[Te4[(rk[2] ) & 0xff] & 0xff]; - - rk[3] = - Td0[Te4[(rk[3] >> 24) ] & 0xff] ^ - Td1[Te4[(rk[3] >> 16) & 0xff] & 0xff] ^ - Td2[Te4[(rk[3] >> 8) & 0xff] & 0xff] ^ - Td3[Te4[(rk[3] ) & 0xff] & 0xff]; + + rk[0]= ( + Td0[Te4[(rk[0] >> 24) ] & 0xff] ^ + Td1[Te4[(rk[0] >> 16) & 0xff] & 0xff] ^ + Td2[Te4[(rk[0] >> 8) & 0xff] & 0xff] ^ + Td3[Te4[(rk[0] ) & 0xff] & 0xff]); + + rk[1]= (Td0[Te4[(rk[1] >> 24) ] & 0xff] ^ + Td1[Te4[(rk[1] >> 16) & 0xff] & 0xff] ^ + Td2[Te4[(rk[1] >> 8) & 0xff] & 0xff] ^ + Td3[Te4[(rk[1] ) & 0xff] & 0xff]); + + rk[2]= (Td0[Te4[(rk[2] >> 24) ] & 0xff] ^ + Td1[Te4[(rk[2] >> 16) & 0xff] & 0xff] ^ + Td2[Te4[(rk[2] >> 8) & 0xff] & 0xff] ^ + Td3[Te4[(rk[2] ) & 0xff] & 0xff]); + + rk[3]= (Td0[Te4[(rk[3] >> 24) ] & 0xff] ^ + Td1[Te4[(rk[3] >> 16) & 0xff] & 0xff] ^ + Td2[Te4[(rk[3] >> 8) & 0xff] & 0xff] ^ + Td3[Te4[(rk[3] ) & 0xff] & 0xff]); } - return Nr; + return nr; } -void rijndaelEncrypt(const uint32 rk[/*4*(Nr + 1)*/], int Nr, - const uint8 pt[16], uint8 ct[16]) + +void rijndaelEncrypt(const uint32 rk[/*4*(Nr + 1)*/], int Nr, + const uint8 pt[16], uint8 ct[16]) { uint32 s0, s1, s2, s3, t0, t1, t2, t3; #ifndef FULL_UNROLL - int r; -#endif /* ?FULL_UNROLL */ + int r; +#endif /* FULL_UNROLL */ - /* - map byte array block to cipher state - and add initial round key: - */ - s0 = GETuint32(pt ) ^ rk[0]; + /* map byte array block to cipher state and add initial round key: */ + s0 = GETuint32(pt ) ^ rk[0]; s1 = GETuint32(pt + 4) ^ rk[1]; s2 = GETuint32(pt + 8) ^ rk[2]; s3 = GETuint32(pt + 12) ^ rk[3]; - + #ifdef FULL_UNROLL /* round 1: */ - t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] - ^ Te3[s3 & 0xff] ^ rk[ 4]; - t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] - ^ Te3[s0 & 0xff] ^ rk[ 5]; - t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] - ^ Te3[s1 & 0xff] ^ rk[ 6]; - t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] - ^ Te3[s2 & 0xff] ^ rk[ 7]; - + t0= (Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] + ^ Te3[s3 & 0xff] ^ rk[ 4]); + t1= (Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] + ^ Te3[s0 & 0xff] ^ rk[ 5]); + t2= (Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] + ^ Te3[s1 & 0xff] ^ rk[ 6]); + t3= (Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] + ^ Te3[s2 & 0xff] ^ rk[ 7]); + /* round 2: */ - s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] - ^ Te3[t3 & 0xff] ^ rk[ 8]; - s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] - ^ Te3[t0 & 0xff] ^ rk[ 9]; - s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] - ^ Te3[t1 & 0xff] ^ rk[10]; - s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] - ^ Te3[t2 & 0xff] ^ rk[11]; - + s0= (Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] + ^ Te3[t3 & 0xff] ^ rk[ 8]); + s1= (Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] + ^ Te3[t0 & 0xff] ^ rk[ 9]); + s2= (Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] + ^ Te3[t1 & 0xff] ^ rk[10]); + s3= (Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] + ^ Te3[t2 & 0xff] ^ rk[11]); + /* round 3: */ - t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] - ^ Te3[s3 & 0xff] ^ rk[12]; - t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] - ^ Te3[s0 & 0xff] ^ rk[13]; - t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] - ^ Te3[s1 & 0xff] ^ rk[14]; - t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] - ^ Te3[s2 & 0xff] ^ rk[15]; - + t0= (Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] + ^ Te3[s3 & 0xff] ^ rk[12]); + t1= (Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] + ^ Te3[s0 & 0xff] ^ rk[13]); + t2= (Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] + ^ Te3[s1 & 0xff] ^ rk[14]); + t3= (Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] + ^ Te3[s2 & 0xff] ^ rk[15]); + /* round 4: */ - s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] - ^ Te3[t3 & 0xff] ^ rk[16]; - s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] - ^ Te3[t0 & 0xff] ^ rk[17]; - s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] - ^ Te3[t1 & 0xff] ^ rk[18]; - s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] - ^ Te3[t2 & 0xff] ^ rk[19]; - + s0= (Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] + ^ Te3[t3 & 0xff] ^ rk[16]); + s1= (Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] + ^ Te3[t0 & 0xff] ^ rk[17]); + s2= (Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] + ^ Te3[t1 & 0xff] ^ rk[18]); + s3= (Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] + ^ Te3[t2 & 0xff] ^ rk[19]); + /* round 5: */ - t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] - ^ Te3[s3 & 0xff] ^ rk[20]; - t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] - ^ Te3[s0 & 0xff] ^ rk[21]; - t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] - ^ Te3[s1 & 0xff] ^ rk[22]; - t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] - ^ Te3[s2 & 0xff] ^ rk[23]; - + t0= (Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] + ^ Te3[s3 & 0xff] ^ rk[20]); + t1= (Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] + ^ Te3[s0 & 0xff] ^ rk[21]); + t2= (Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] + ^ Te3[s1 & 0xff] ^ rk[22]); + t3= (Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] + ^ Te3[s2 & 0xff] ^ rk[23]); + /* round 6: */ - s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] - ^ Te3[t3 & 0xff] ^ rk[24]; - s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] - ^ Te3[t0 & 0xff] ^ rk[25]; - s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] - ^ Te3[t1 & 0xff] ^ rk[26]; - s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] - ^ Te3[t2 & 0xff] ^ rk[27]; - + s0= (Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] + ^ Te3[t3 & 0xff] ^ rk[24]); + s1= (Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] + ^ Te3[t0 & 0xff] ^ rk[25]); + s2= (Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] + ^ Te3[t1 & 0xff] ^ rk[26]); + s3= (Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] + ^ Te3[t2 & 0xff] ^ rk[27]); + /* round 7: */ - t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] - ^ Te3[s3 & 0xff] ^ rk[28]; - t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] - ^ Te3[s0 & 0xff] ^ rk[29]; - t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] - ^ Te3[s1 & 0xff] ^ rk[30]; - t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] - ^ Te3[s2 & 0xff] ^ rk[31]; - + t0= (Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] + ^ Te3[s3 & 0xff] ^ rk[28]); + t1= (Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] + ^ Te3[s0 & 0xff] ^ rk[29]); + t2= (Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] + ^ Te3[s1 & 0xff] ^ rk[30]); + t3= (Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] + ^ Te3[s2 & 0xff] ^ rk[31]); + /* round 8: */ - s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] - ^ Te3[t3 & 0xff] ^ rk[32]; - s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] - ^ Te3[t0 & 0xff] ^ rk[33]; - s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] - ^ Te3[t1 & 0xff] ^ rk[34]; - s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] - ^ Te3[t2 & 0xff] ^ rk[35]; - + s0= (Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] + ^ Te3[t3 & 0xff] ^ rk[32]); + s1= (Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] + ^ Te3[t0 & 0xff] ^ rk[33]); + s2= (Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] + ^ Te3[t1 & 0xff] ^ rk[34]); + s3= (Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] + ^ Te3[t2 & 0xff] ^ rk[35]); + /* round 9: */ - t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] - ^ Te3[s3 & 0xff] ^ rk[36]; - t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] - ^ Te3[s0 & 0xff] ^ rk[37]; - t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] - ^ Te3[s1 & 0xff] ^ rk[38]; - t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] - ^ Te3[s2 & 0xff] ^ rk[39]; - - if (Nr > 10) - { + t0= (Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] + ^ Te3[s3 & 0xff] ^ rk[36]); + t1= (Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] + ^ Te3[s0 & 0xff] ^ rk[37]); + t2= (Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] + ^ Te3[s1 & 0xff] ^ rk[38]); + t3= (Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] + ^ Te3[s2 & 0xff] ^ rk[39]); + + if (Nr > 10) + { /* round 10: */ - s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] - ^ Te3[t3 & 0xff] ^ rk[40]; - s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] - ^ Te3[t0 & 0xff] ^ rk[41]; - s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] - ^ Te3[t1 & 0xff] ^ rk[42]; - s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] - ^ Te3[t2 & 0xff] ^ rk[43]; - + s0= (Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] + ^ Te3[t3 & 0xff] ^ rk[40]); + s1= (Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] + ^ Te3[t0 & 0xff] ^ rk[41]); + s2= (Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] + ^ Te3[t1 & 0xff] ^ rk[42]); + s3= (Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] + ^ Te3[t2 & 0xff] ^ rk[43]); + /* round 11: */ - t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] - ^ Te3[s3 & 0xff] ^ rk[44]; - t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] - ^ Te3[s0 & 0xff] ^ rk[45]; - t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] - ^ Te3[s1 & 0xff] ^ rk[46]; - t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] - ^ Te3[s2 & 0xff] ^ rk[47]; - - if (Nr > 12) + t0= (Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] + ^ Te3[s3 & 0xff] ^ rk[44]); + t1= (Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] + ^ Te3[s0 & 0xff] ^ rk[45]); + t2= (Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] + ^ Te3[s1 & 0xff] ^ rk[46]); + t3= (Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] + ^ Te3[s2 & 0xff] ^ rk[47]); + + if (Nr > 12) { /* round 12: */ - s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] - ^ Te3[t3 & 0xff] ^ rk[48]; - s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] - ^ Te3[t0 & 0xff] ^ rk[49]; - s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] - ^ Te3[t1 & 0xff] ^ rk[50]; - s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] - ^ Te3[t2 & 0xff] ^ rk[51]; - - /* round 13: */ - t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] - ^ Te3[s3 & 0xff] ^ rk[52]; - t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] - ^ Te3[s0 & 0xff] ^ rk[53]; - t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] - ^ Te3[s1 & 0xff] ^ rk[54]; - t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] - ^ Te3[s2 & 0xff] ^ rk[55]; + s0= (Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] + ^ Te3[t3 & 0xff] ^ rk[48]); + s1= (Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] + ^ Te3[t0 & 0xff] ^ rk[49]); + s2= (Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] + ^ Te3[t1 & 0xff] ^ rk[50]); + s3= (Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] + ^ Te3[t2 & 0xff] ^ rk[51]); + + /* round 13: */ + t0= (Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] + ^ Te3[s3 & 0xff] ^ rk[52]); + t1= (Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] + ^ Te3[s0 & 0xff] ^ rk[53]); + t2= (Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] + ^ Te3[s1 & 0xff] ^ rk[54]); + t3= (Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] + ^ Te3[s2 & 0xff] ^ rk[55]); } } rk += Nr << 2; #else /* !FULL_UNROLL */ /* Nr - 1 full rounds: */ - + r = Nr >> 1; - for (;;) + for (;;) { - t0 = - Te0[(s0 >> 24) ] ^ - Te1[(s1 >> 16) & 0xff] ^ - Te2[(s2 >> 8) & 0xff] ^ - Te3[(s3 ) & 0xff] ^ - rk[4]; - - t1 = - Te0[(s1 >> 24) ] ^ - Te1[(s2 >> 16) & 0xff] ^ - Te2[(s3 >> 8) & 0xff] ^ - Te3[(s0 ) & 0xff] ^ - rk[5]; - - t2 = - Te0[(s2 >> 24) ] ^ - Te1[(s3 >> 16) & 0xff] ^ - Te2[(s0 >> 8) & 0xff] ^ - Te3[(s1 ) & 0xff] ^ - rk[6]; - - t3 = - Te0[(s3 >> 24) ] ^ - Te1[(s0 >> 16) & 0xff] ^ - Te2[(s1 >> 8) & 0xff] ^ - Te3[(s2 ) & 0xff] ^ - rk[7]; - - rk += 8; - if (--r == 0) - { + t0= (Te0[(s0 >> 24) ] ^ + Te1[(s1 >> 16) & 0xff] ^ + Te2[(s2 >> 8) & 0xff] ^ + Te3[(s3 ) & 0xff] ^ + rk[4]); + + t1= (Te0[(s1 >> 24) ] ^ + Te1[(s2 >> 16) & 0xff] ^ + Te2[(s3 >> 8) & 0xff] ^ + Te3[(s0 ) & 0xff] ^ + rk[5]); + + t2= (Te0[(s2 >> 24) ] ^ + Te1[(s3 >> 16) & 0xff] ^ + Te2[(s0 >> 8) & 0xff] ^ + Te3[(s1 ) & 0xff] ^ + rk[6]); + + t3= (Te0[(s3 >> 24) ] ^ + Te1[(s0 >> 16) & 0xff] ^ + Te2[(s1 >> 8) & 0xff] ^ + Te3[(s2 ) & 0xff] ^ + rk[7]); + + rk+= 8; + if (--r == 0) break; - } - - s0 = - Te0[(t0 >> 24) ] ^ - Te1[(t1 >> 16) & 0xff] ^ - Te2[(t2 >> 8) & 0xff] ^ - Te3[(t3 ) & 0xff] ^ - rk[0]; - - s1 = - Te0[(t1 >> 24) ] ^ - Te1[(t2 >> 16) & 0xff] ^ - Te2[(t3 >> 8) & 0xff] ^ - Te3[(t0 ) & 0xff] ^ - rk[1]; - - s2 = - Te0[(t2 >> 24) ] ^ - Te1[(t3 >> 16) & 0xff] ^ - Te2[(t0 >> 8) & 0xff] ^ - Te3[(t1 ) & 0xff] ^ - rk[2]; - - s3 = - Te0[(t3 >> 24) ] ^ - Te1[(t0 >> 16) & 0xff] ^ - Te2[(t1 >> 8) & 0xff] ^ - Te3[(t2 ) & 0xff] ^ - rk[3]; + + s0= (Te0[(t0 >> 24) ] ^ + Te1[(t1 >> 16) & 0xff] ^ + Te2[(t2 >> 8) & 0xff] ^ + Te3[(t3 ) & 0xff] ^ + rk[0]); + + s1= (Te0[(t1 >> 24) ] ^ + Te1[(t2 >> 16) & 0xff] ^ + Te2[(t3 >> 8) & 0xff] ^ + Te3[(t0 ) & 0xff] ^ + rk[1]); + + s2= (Te0[(t2 >> 24) ] ^ + Te1[(t3 >> 16) & 0xff] ^ + Te2[(t0 >> 8) & 0xff] ^ + Te3[(t1 ) & 0xff] ^ + rk[2]); + + s3= (Te0[(t3 >> 24) ] ^ + Te1[(t0 >> 16) & 0xff] ^ + Te2[(t1 >> 8) & 0xff] ^ + Te3[(t2 ) & 0xff] ^ + rk[3]); } -#endif /* ?FULL_UNROLL */ +#endif /* FULL_UNROLL */ - /* - apply last round and - map cipher state to byte array block: - */ - s0 = - (Te4[(t0 >> 24) ] & 0xff000000) ^ - (Te4[(t1 >> 16) & 0xff] & 0x00ff0000) ^ - (Te4[(t2 >> 8) & 0xff] & 0x0000ff00) ^ - (Te4[(t3 ) & 0xff] & 0x000000ff) ^ - rk[0]; - PUTuint32(ct , s0); - - s1 = - (Te4[(t1 >> 24) ] & 0xff000000) ^ - (Te4[(t2 >> 16) & 0xff] & 0x00ff0000) ^ - (Te4[(t3 >> 8) & 0xff] & 0x0000ff00) ^ - (Te4[(t0 ) & 0xff] & 0x000000ff) ^ - rk[1]; + /* Apply last round and map cipher state to byte array block: */ + s0= ((Te4[(t0 >> 24) ] & 0xff000000) ^ + (Te4[(t1 >> 16) & 0xff] & 0x00ff0000) ^ + (Te4[(t2 >> 8) & 0xff] & 0x0000ff00) ^ + (Te4[(t3 ) & 0xff] & 0x000000ff) ^ + rk[0]); + PUTuint32(ct , s0); + + s1= ((Te4[(t1 >> 24) ] & 0xff000000) ^ + (Te4[(t2 >> 16) & 0xff] & 0x00ff0000) ^ + (Te4[(t3 >> 8) & 0xff] & 0x0000ff00) ^ + (Te4[(t0 ) & 0xff] & 0x000000ff) ^ + rk[1]); PUTuint32(ct + 4, s1); - - s2 = - (Te4[(t2 >> 24) ] & 0xff000000) ^ - (Te4[(t3 >> 16) & 0xff] & 0x00ff0000) ^ - (Te4[(t0 >> 8) & 0xff] & 0x0000ff00) ^ - (Te4[(t1 ) & 0xff] & 0x000000ff) ^ - rk[2]; + + s2= ((Te4[(t2 >> 24) ] & 0xff000000) ^ + (Te4[(t3 >> 16) & 0xff] & 0x00ff0000) ^ + (Te4[(t0 >> 8) & 0xff] & 0x0000ff00) ^ + (Te4[(t1 ) & 0xff] & 0x000000ff) ^ + rk[2]); PUTuint32(ct + 8, s2); - - s3 = - (Te4[(t3 >> 24) ] & 0xff000000) ^ - (Te4[(t0 >> 16) & 0xff] & 0x00ff0000) ^ - (Te4[(t1 >> 8) & 0xff] & 0x0000ff00) ^ - (Te4[(t2 ) & 0xff] & 0x000000ff) ^ - rk[3]; + + s3= ((Te4[(t3 >> 24) ] & 0xff000000) ^ + (Te4[(t0 >> 16) & 0xff] & 0x00ff0000) ^ + (Te4[(t1 >> 8) & 0xff] & 0x0000ff00) ^ + (Te4[(t2 ) & 0xff] & 0x000000ff) ^ + rk[3]); PUTuint32(ct + 12, s3); } -void rijndaelDecrypt(const uint32 rk[/*4*(Nr + 1)*/], int Nr, - const uint8 ct[16], uint8 pt[16]) + +void rijndaelDecrypt(const uint32 rk[/*4*(Nr + 1)*/], int Nr, + const uint8 ct[16], uint8 pt[16]) { uint32 s0, s1, s2, s3, t0, t1, t2, t3; #ifndef FULL_UNROLL int r; -#endif /* ?FULL_UNROLL */ +#endif /* FULL_UNROLL */ - /* - map byte array block to cipher state - and add initial round key: - */ - - s0 = GETuint32(ct ) ^ rk[0]; + /* Map byte array block to cipher state and add initial round key: */ + + s0 = GETuint32(ct ) ^ rk[0]; s1 = GETuint32(ct + 4) ^ rk[1]; s2 = GETuint32(ct + 8) ^ rk[2]; s3 = GETuint32(ct + 12) ^ rk[3]; - + #ifdef FULL_UNROLL /* round 1: */ - t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] - ^ Td3[s1 & 0xff] ^ rk[ 4]; - t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] - ^ Td3[s2 & 0xff] ^ rk[ 5]; - t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] - ^ Td3[s3 & 0xff] ^ rk[ 6]; - t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] - ^ Td3[s0 & 0xff] ^ rk[ 7]; - + t0= (Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] + ^ Td3[s1 & 0xff] ^ rk[ 4]); + t1= (Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] + ^ Td3[s2 & 0xff] ^ rk[ 5]); + t2= (Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] + ^ Td3[s3 & 0xff] ^ rk[ 6]); + t3= (Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] + ^ Td3[s0 & 0xff] ^ rk[ 7]); + /* round 2: */ - s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] - ^ Td3[t1 & 0xff] ^ rk[ 8]; - s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] - ^ Td3[t2 & 0xff] ^ rk[ 9]; - s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] - ^ Td3[t3 & 0xff] ^ rk[10]; - s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] - ^ Td3[t0 & 0xff] ^ rk[11]; - + s0= (Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] + ^ Td3[t1 & 0xff] ^ rk[ 8]); + s1= (Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] + ^ Td3[t2 & 0xff] ^ rk[ 9]); + s2= (Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] + ^ Td3[t3 & 0xff] ^ rk[10]); + s3= (Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] + ^ Td3[t0 & 0xff] ^ rk[11]); + /* round 3: */ - t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] - ^ Td3[s1 & 0xff] ^ rk[12]; - t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] - ^ Td3[s2 & 0xff] ^ rk[13]; - t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] - ^ Td3[s3 & 0xff] ^ rk[14]; - t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] - ^ Td3[s0 & 0xff] ^ rk[15]; - + t0= (Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] + ^ Td3[s1 & 0xff] ^ rk[12]); + t1= (Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] + ^ Td3[s2 & 0xff] ^ rk[13]); + t2= (Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] + ^ Td3[s3 & 0xff] ^ rk[14]); + t3= (Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] + ^ Td3[s0 & 0xff] ^ rk[15]); + /* round 4: */ - s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] - ^ Td3[t1 & 0xff] ^ rk[16]; - s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] - ^ Td3[t2 & 0xff] ^ rk[17]; - s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] - ^ Td3[t3 & 0xff] ^ rk[18]; - s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] - ^ Td3[t0 & 0xff] ^ rk[19]; - + s0= (Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] + ^ Td3[t1 & 0xff] ^ rk[16]); + s1= (Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] + ^ Td3[t2 & 0xff] ^ rk[17]); + s2= (Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] + ^ Td3[t3 & 0xff] ^ rk[18]); + s3= (Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] + ^ Td3[t0 & 0xff] ^ rk[19]); + /* round 5: */ - t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] - ^ Td3[s1 & 0xff] ^ rk[20]; - t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] - ^ Td3[s2 & 0xff] ^ rk[21]; - t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] - ^ Td3[s3 & 0xff] ^ rk[22]; - t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] - ^ Td3[s0 & 0xff] ^ rk[23]; - + t0= (Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] + ^ Td3[s1 & 0xff] ^ rk[20]); + t1= (Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] + ^ Td3[s2 & 0xff] ^ rk[21]); + t2= (Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] + ^ Td3[s3 & 0xff] ^ rk[22]); + t3= (Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] + ^ Td3[s0 & 0xff] ^ rk[23]); + /* round 6: */ - s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] - ^ Td3[t1 & 0xff] ^ rk[24]; - s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] - ^ Td3[t2 & 0xff] ^ rk[25]; - s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] - ^ Td3[t3 & 0xff] ^ rk[26]; - s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] - ^ Td3[t0 & 0xff] ^ rk[27]; - + s0= (Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] + ^ Td3[t1 & 0xff] ^ rk[24]); + s1= (Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] + ^ Td3[t2 & 0xff] ^ rk[25]); + s2= (Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] + ^ Td3[t3 & 0xff] ^ rk[26]); + s3= (Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] + ^ Td3[t0 & 0xff] ^ rk[27]); + /* round 7: */ - t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] - ^ Td3[s1 & 0xff] ^ rk[28]; - t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] - ^ Td3[s2 & 0xff] ^ rk[29]; - t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] - ^ Td3[s3 & 0xff] ^ rk[30]; - t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] - ^ Td3[s0 & 0xff] ^ rk[31]; - + t0= (Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] + ^ Td3[s1 & 0xff] ^ rk[28]); + t1= (Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] + ^ Td3[s2 & 0xff] ^ rk[29]); + t2= (Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] + ^ Td3[s3 & 0xff] ^ rk[30]); + t3= (Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] + ^ Td3[s0 & 0xff] ^ rk[31]); + /* round 8: */ - s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] - ^ Td3[t1 & 0xff] ^ rk[32]; - s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] - ^ Td3[t2 & 0xff] ^ rk[33]; - s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] - ^ Td3[t3 & 0xff] ^ rk[34]; - s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] - ^ Td3[t0 & 0xff] ^ rk[35]; - + s0= (Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] + ^ Td3[t1 & 0xff] ^ rk[32]); + s1= (Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] + ^ Td3[t2 & 0xff] ^ rk[33]); + s2= (Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] + ^ Td3[t3 & 0xff] ^ rk[34]); + s3= (Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] + ^ Td3[t0 & 0xff] ^ rk[35]); + /* round 9: */ - t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] - ^ Td3[s1 & 0xff] ^ rk[36]; - t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] - ^ Td3[s2 & 0xff] ^ rk[37]; - t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] - ^ Td3[s3 & 0xff] ^ rk[38]; - t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] - ^ Td3[s0 & 0xff] ^ rk[39]; - - if (Nr > 10) + t0= (Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] + ^ Td3[s1 & 0xff] ^ rk[36]); + t1= (Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] + ^ Td3[s2 & 0xff] ^ rk[37]); + t2= (Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] + ^ Td3[s3 & 0xff] ^ rk[38]); + t3= (Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] + ^ Td3[s0 & 0xff] ^ rk[39]); + + if (Nr > 10) { /* round 10: */ - s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] - ^ Td3[t1 & 0xff] ^ rk[40]; - s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] - ^ Td3[t2 & 0xff] ^ rk[41]; - s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] - ^ Td3[t3 & 0xff] ^ rk[42]; - s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] - ^ Td3[t0 & 0xff] ^ rk[43]; - + s0= (Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] + ^ Td3[t1 & 0xff] ^ rk[40]); + s1= (Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] + ^ Td3[t2 & 0xff] ^ rk[41]); + s2= (Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] + ^ Td3[t3 & 0xff] ^ rk[42]); + s3= (Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] + ^ Td3[t0 & 0xff] ^ rk[43]); + /* round 11: */ - t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] - ^ Td3[s1 & 0xff] ^ rk[44]; - t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] - ^ Td3[s2 & 0xff] ^ rk[45]; - t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] - ^ Td3[s3 & 0xff] ^ rk[46]; - t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] - ^ Td3[s0 & 0xff] ^ rk[47]; - - if (Nr > 12) + t0= (Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] + ^ Td3[s1 & 0xff] ^ rk[44]); + t1= (Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] + ^ Td3[s2 & 0xff] ^ rk[45]); + t2= (Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] + ^ Td3[s3 & 0xff] ^ rk[46]); + t3= (Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] + ^ Td3[s0 & 0xff] ^ rk[47]); + + if (Nr > 12) { /* round 12: */ - s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] - ^ Td3[t1 & 0xff] ^ rk[48]; - s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] - ^ Td3[t2 & 0xff] ^ rk[49]; - s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] - ^ Td3[t3 & 0xff] ^ rk[50]; - s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] - ^ Td3[t0 & 0xff] ^ rk[51]; - + s0= (Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] + ^ Td3[t1 & 0xff] ^ rk[48]); + s1= (Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] + ^ Td3[t2 & 0xff] ^ rk[49]); + s2= (Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] + ^ Td3[t3 & 0xff] ^ rk[50]); + s3= (Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] + ^ Td3[t0 & 0xff] ^ rk[51]); + /* round 13: */ - t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] - ^ Td3[s1 & 0xff] ^ rk[52]; - t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] - ^ Td3[s2 & 0xff] ^ rk[53]; - t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] - ^ Td3[s3 & 0xff] ^ rk[54]; - t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] - ^ Td3[s0 & 0xff] ^ rk[55]; + t0= (Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] + ^ Td3[s1 & 0xff] ^ rk[52]); + t1= (Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] + ^ Td3[s2 & 0xff] ^ rk[53]); + t2= (Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] + ^ Td3[s3 & 0xff] ^ rk[54]); + t3= (Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] + ^ Td3[s0 & 0xff] ^ rk[55]); } } rk += Nr << 2; #else /* !FULL_UNROLL */ /* Nr - 1 full rounds: */ - r = Nr >> 1; - for (;;) + r= (Nr >> 1); + for (;;) { - t0 = - Td0[(s0 >> 24) ] ^ - Td1[(s3 >> 16) & 0xff] ^ - Td2[(s2 >> 8) & 0xff] ^ - Td3[(s1 ) & 0xff] ^ - rk[4]; - - t1 = - Td0[(s1 >> 24) ] ^ - Td1[(s0 >> 16) & 0xff] ^ - Td2[(s3 >> 8) & 0xff] ^ - Td3[(s2 ) & 0xff] ^ - rk[5]; - - t2 = - Td0[(s2 >> 24) ] ^ - Td1[(s1 >> 16) & 0xff] ^ - Td2[(s0 >> 8) & 0xff] ^ - Td3[(s3 ) & 0xff] ^ - rk[6]; - - t3 = - Td0[(s3 >> 24) ] ^ - Td1[(s2 >> 16) & 0xff] ^ - Td2[(s1 >> 8) & 0xff] ^ - Td3[(s0 ) & 0xff] ^ - rk[7]; - - rk += 8; - if (--r == 0) - { + t0= (Td0[(s0 >> 24) ] ^ + Td1[(s3 >> 16) & 0xff] ^ + Td2[(s2 >> 8) & 0xff] ^ + Td3[(s1 ) & 0xff] ^ + rk[4]); + + t1= (Td0[(s1 >> 24) ] ^ + Td1[(s0 >> 16) & 0xff] ^ + Td2[(s3 >> 8) & 0xff] ^ + Td3[(s2 ) & 0xff] ^ + rk[5]); + + t2= (Td0[(s2 >> 24) ] ^ + Td1[(s1 >> 16) & 0xff] ^ + Td2[(s0 >> 8) & 0xff] ^ + Td3[(s3 ) & 0xff] ^ + rk[6]); + + t3= (Td0[(s3 >> 24) ] ^ + Td1[(s2 >> 16) & 0xff] ^ + Td2[(s1 >> 8) & 0xff] ^ + Td3[(s0 ) & 0xff] ^ + rk[7]); + + rk+= 8; + if (--r == 0) break; - } - s0 = - Td0[(t0 >> 24) ] ^ - Td1[(t3 >> 16) & 0xff] ^ - Td2[(t2 >> 8) & 0xff] ^ - Td3[(t1 ) & 0xff] ^ - rk[0]; - - s1 = - Td0[(t1 >> 24) ] ^ - Td1[(t0 >> 16) & 0xff] ^ - Td2[(t3 >> 8) & 0xff] ^ - Td3[(t2 ) & 0xff] ^ - rk[1]; - - s2 = - Td0[(t2 >> 24) ] ^ - Td1[(t1 >> 16) & 0xff] ^ - Td2[(t0 >> 8) & 0xff] ^ - Td3[(t3 ) & 0xff] ^ - rk[2]; - - s3 = - Td0[(t3 >> 24) ] ^ - Td1[(t2 >> 16) & 0xff] ^ - Td2[(t1 >> 8) & 0xff] ^ - Td3[(t0 ) & 0xff] ^ - rk[3]; + s0= (Td0[(t0 >> 24) ] ^ + Td1[(t3 >> 16) & 0xff] ^ + Td2[(t2 >> 8) & 0xff] ^ + Td3[(t1 ) & 0xff] ^ + rk[0]); + + s1= (Td0[(t1 >> 24) ] ^ + Td1[(t0 >> 16) & 0xff] ^ + Td2[(t3 >> 8) & 0xff] ^ + Td3[(t2 ) & 0xff] ^ + rk[1]); + + s2= (Td0[(t2 >> 24) ] ^ + Td1[(t1 >> 16) & 0xff] ^ + Td2[(t0 >> 8) & 0xff] ^ + Td3[(t3 ) & 0xff] ^ + rk[2]); + + s3= (Td0[(t3 >> 24) ] ^ + Td1[(t2 >> 16) & 0xff] ^ + Td2[(t1 >> 8) & 0xff] ^ + Td3[(t0 ) & 0xff] ^ + rk[3]); } - -#endif /* ?FULL_UNROLL */ - /* - apply last round and - map cipher state to byte array block: - */ - - s0 = - (Td4[(t0 >> 24) ] & 0xff000000) ^ - (Td4[(t3 >> 16) & 0xff] & 0x00ff0000) ^ - (Td4[(t2 >> 8) & 0xff] & 0x0000ff00) ^ - (Td4[(t1 ) & 0xff] & 0x000000ff) ^ - rk[0]; - PUTuint32(pt , s0); - - s1 = - (Td4[(t1 >> 24) ] & 0xff000000) ^ - (Td4[(t0 >> 16) & 0xff] & 0x00ff0000) ^ - (Td4[(t3 >> 8) & 0xff] & 0x0000ff00) ^ - (Td4[(t2 ) & 0xff] & 0x000000ff) ^ - rk[1]; +#endif /* FULL_UNROLL */ + + /* Apply last round and map cipher state to byte array block: */ + + s0= ((Td4[(t0 >> 24) ] & 0xff000000) ^ + (Td4[(t3 >> 16) & 0xff] & 0x00ff0000) ^ + (Td4[(t2 >> 8) & 0xff] & 0x0000ff00) ^ + (Td4[(t1 ) & 0xff] & 0x000000ff) ^ + rk[0]); + PUTuint32(pt , s0); + + s1= ((Td4[(t1 >> 24) ] & 0xff000000) ^ + (Td4[(t0 >> 16) & 0xff] & 0x00ff0000) ^ + (Td4[(t3 >> 8) & 0xff] & 0x0000ff00) ^ + (Td4[(t2 ) & 0xff] & 0x000000ff) ^ + rk[1]); PUTuint32(pt + 4, s1); - - s2 = - (Td4[(t2 >> 24) ] & 0xff000000) ^ - (Td4[(t1 >> 16) & 0xff] & 0x00ff0000) ^ - (Td4[(t0 >> 8) & 0xff] & 0x0000ff00) ^ - (Td4[(t3 ) & 0xff] & 0x000000ff) ^ - rk[2]; - + + s2= ((Td4[(t2 >> 24) ] & 0xff000000) ^ + (Td4[(t1 >> 16) & 0xff] & 0x00ff0000) ^ + (Td4[(t0 >> 8) & 0xff] & 0x0000ff00) ^ + (Td4[(t3 ) & 0xff] & 0x000000ff) ^ + rk[2]); PUTuint32(pt + 8, s2); - s3 = - (Td4[(t3 >> 24) ] & 0xff000000) ^ - (Td4[(t2 >> 16) & 0xff] & 0x00ff0000) ^ - (Td4[(t1 >> 8) & 0xff] & 0x0000ff00) ^ - (Td4[(t0 ) & 0xff] & 0x000000ff) ^ - rk[3]; - PUTuint32(pt + 12, s3); + + s3= ((Td4[(t3 >> 24) ] & 0xff000000) ^ + (Td4[(t2 >> 16) & 0xff] & 0x00ff0000) ^ + (Td4[(t1 >> 8) & 0xff] & 0x0000ff00) ^ + (Td4[(t0 ) & 0xff] & 0x000000ff) ^ + rk[3]); + PUTuint32(pt + 12, s3); } diff --git a/mysys/sha1.c b/mysys/sha1.c index 82ccab2c6ce..3b4bac84d08 100644 --- a/mysys/sha1.c +++ b/mysys/sha1.c @@ -4,54 +4,49 @@ it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - + /* - sha1.c - Original Source from: http://www.faqs.org/rfcs/rfc3174.html - - Description: - This file implements the Secure Hashing Algorithm 1 as - defined in FIPS PUB 180-1 published April 17, 1995. - - The SHA-1, produces a 160-bit message digest for a given - data stream. It should take about 2**n steps to find a - message with the same digest as a given message and - 2**(n/2) to find any two messages with the same digest, - when n is the digest size in bits. Therefore, this - algorithm can serve as a means of providing a - "fingerprint" for a message. - - Portability Issues: - SHA-1 is defined in terms of 32-bit "words". This code - uses <stdint.h> (included via "sha1.h" to define 32 and 8 - bit unsigned integer types. If your C compiler does not - support 32 bit unsigned integers, this code is not - appropriate. - - Caveats: - SHA-1 is designed to work with messages less than 2^64 bits - long. Although SHA-1 allows a message digest to be generated - for messages of any number of bits less than 2^64, this - implementation only works with messages with a length that is - a multiple of the size of an 8-bit character. - -*/ - -/* - Modified 2002 by Peter Zaitsev to - - fit to new prototypes according to MySQL standard - - Some optimizations - - All checking is now done in debug only mode - - More comments + Original Source from: http://www.faqs.org/rfcs/rfc3174.html + + DESCRIPTION + This file implements the Secure Hashing Algorithm 1 as + defined in FIPS PUB 180-1 published April 17, 1995. + + The SHA-1, produces a 160-bit message digest for a given data + stream. It should take about 2**n steps to find a message with the + same digest as a given message and 2**(n/2) to find any two + messages with the same digest, when n is the digest size in bits. + Therefore, this algorithm can serve as a means of providing a + "fingerprint" for a message. + + PORTABILITY ISSUES + SHA-1 is defined in terms of 32-bit "words". This code uses + <stdint.h> (included via "sha1.h" to define 32 and 8 bit unsigned + integer types. If your C compiler does not support 32 bit unsigned + integers, this code is not appropriate. + + CAVEATS + SHA-1 is designed to work with messages less than 2^64 bits long. + Although SHA-1 allows a message digest to be generated for messages + of any number of bits less than 2^64, this implementation only + works with messages with a length that is a multiple of the size of + an 8-bit character. + + CHANGES + 2002 by Peter Zaitsev to + - fit to new prototypes according to MySQL standard + - Some optimizations + - All checking is now done in debug only mode + - More comments */ #include "my_global.h" @@ -59,32 +54,33 @@ #include "sha1.h" /* - Define the SHA1 circular left shift macro + Define the SHA1 circular left shift macro */ - + #define SHA1CircularShift(bits,word) \ - (((word) << (bits)) | ((word) >> (32-(bits)))) + (((word) << (bits)) | ((word) >> (32-(bits)))) /* Local Function Prototyptes */ -void SHA1PadMessage(SHA1_CONTEXT*); -void SHA1ProcessMessageBlock(SHA1_CONTEXT*); +static void SHA1PadMessage(SHA1_CONTEXT*); +static void SHA1ProcessMessageBlock(SHA1_CONTEXT*); + /* - sha1_reset - - Description: - This function will initialize the SHA1Context in preparation - for computing a new SHA1 message digest. - - Parameters: - context: [in/out] - The context to reset. - - Returns: - sha Error Code. - + Initialize SHA1Context + + SYNOPSIS + sha1_reset() + context [in/out] The context to reset. + + DESCRIPTION + This function will initialize the SHA1Context in preparation + for computing a new SHA1 message digest. + + RETURN + SHA_SUCCESS ok + != SHA_SUCCESS sha Error Code. */ - + const uint32 sha_const_key[5]= { @@ -98,17 +94,14 @@ const uint32 sha_const_key[5]= int sha1_reset(SHA1_CONTEXT *context) { - -#ifndef DBUG_OFF +#ifndef DBUG_OFF if (!context) - { return SHA_NULL; - } -#endif +#endif + + context->Length = 0; + context->Message_Block_Index = 0; - context->Length = 0; - context->Message_Block_Index = 0; - context->Intermediate_Hash[0] = sha_const_key[0]; context->Intermediate_Hash[1] = sha_const_key[1]; context->Intermediate_Hash[2] = sha_const_key[2]; @@ -121,165 +114,124 @@ int sha1_reset(SHA1_CONTEXT *context) return SHA_SUCCESS; } + /* - sha1_result - - Description: - This function will return the 160-bit message digest into the - Message_Digest array provided by the caller. - NOTE: The first octet of hash is stored in the 0th element, - the last octet of hash in the 19th element. - - Parameters: - context: [in/out] - The context to use to calculate the SHA-1 hash. - Message_Digest: [out] - Where the digest is returned. - - Returns: - sha Error Code. - + Return the 160-bit message digest into the array provided by the caller + + SYNOPSIS + sha1_result() + context [in/out] The context to use to calculate the SHA-1 hash. + Message_Digest: [out] Where the digest is returned. + + DESCRIPTION + NOTE: The first octet of hash is stored in the 0th element, + the last octet of hash in the 19th element. + + RETURN + SHA_SUCCESS ok + != SHA_SUCCESS sha Error Code. */ -int sha1_result( SHA1_CONTEXT *context, - uint8 Message_Digest[SHA1_HASH_SIZE]) +int sha1_result(SHA1_CONTEXT *context, + uint8 Message_Digest[SHA1_HASH_SIZE]) { int i; - -#ifndef DBUG_OFF + +#ifndef DBUG_OFF if (!context || !Message_Digest) - { return SHA_NULL; - } if (context->Corrupted) - { return context->Corrupted; - } +#endif if (!context->Computed) { - -#endif SHA1PadMessage(context); /* message may be sensitive, clear it out */ bzero((char*) context->Message_Block,64); context->Length = 0; /* and clear length */ context->Computed = 1; - -#ifndef DBUG_OFF } -#endif for (i = 0; i < SHA1_HASH_SIZE; i++) - { - Message_Digest[i] = (context->Intermediate_Hash[i>>2] >> 8 - * ( 3 - ( i & 0x03 ) )); - } - + Message_Digest[i] = (context->Intermediate_Hash[i>>2] >> 8 + * ( 3 - ( i & 0x03 ) )); return SHA_SUCCESS; } + /* - sha1_input - - Description: - This function accepts an array of octets as the next portion - of the message. - - Parameters: - context: [in/out] - The SHA context to update - message_array: [in] - An array of characters representing the next portion of - the message. - length: [in] - The length of the message in message_array - - Returns: - sha Error Code. - + Accepts an array of octets as the next portion of the message. + + SYNOPSIS + sha1_input() + context [in/out] The SHA context to update + message_array An array of characters representing the next portion + of the message. + length The length of the message in message_array + + RETURN + SHA_SUCCESS ok + != SHA_SUCCESS sha Error Code. */ int sha1_input(SHA1_CONTEXT *context, const uint8 *message_array, - unsigned length) + unsigned length) { if (!length) - { return SHA_SUCCESS; - } -#ifndef DBUG_OFF + +#ifndef DBUG_OFF /* We assume client konows what it is doing in non-debug mode */ if (!context || !message_array) - { return SHA_NULL; - } if (context->Computed) - { - context->Corrupted = SHA_STATE_ERROR; - return SHA_STATE_ERROR; - } - + return (context->Corrupted= SHA_STATE_ERROR); if (context->Corrupted) - { return context->Corrupted; - } -#endif +#endif while (length--) { - context->Message_Block[context->Message_Block_Index++] = - (*message_array & 0xFF); - context->Length += 8; /* Length is in bits */ - -#ifndef DBUG_OFF - /* - Then we're not debugging we assume we never will get message longer - 2^64 bits. + context->Message_Block[context->Message_Block_Index++]= + (*message_array & 0xFF); + context->Length += 8; /* Length is in bits */ + +#ifndef DBUG_OFF + /* + Then we're not debugging we assume we never will get message longer + 2^64 bits. */ if (context->Length == 0) - { - /* Message is too long */ - context->Corrupted = 1; - return 1; - } -#endif - + return (context->Corrupted= 1); /* Message is too long */ +#endif + if (context->Message_Block_Index == 64) { SHA1ProcessMessageBlock(context); } - message_array++; + message_array++; } - return SHA_SUCCESS; } + /* - SHA1ProcessMessageBlock - - Description: - This function will process the next 512 bits of the message - stored in the Message_Block array. - - Parameters: - None. - - Returns: - Nothing. - - Comments: - - Many of the variable names in this code, especially the - single character names, were used because those were the - names used in the publication. - - + Process the next 512 bits of the message stored in the Message_Block array. + + SYNOPSIS + SHA1ProcessMessageBlock() + + DESCRIPTION + Many of the variable names in this code, especially the single + character names, were used because those were the names used in + the publication. */ -/* Constants defined in SHA-1 */ -static const uint32 K[]= -{ +/* Constants defined in SHA-1 */ +static const uint32 K[]= +{ 0x5A827999, 0x6ED9EBA1, 0x8F1BBCDC, @@ -287,17 +239,17 @@ static const uint32 K[]= }; -void SHA1ProcessMessageBlock(SHA1_CONTEXT *context) +static void SHA1ProcessMessageBlock(SHA1_CONTEXT *context) { - int t; /* Loop counter */ - uint32 temp; /* Temporary word value */ - uint32 W[80]; /* Word sequence */ - uint32 A, B, C, D, E; /* Word buffers */ + int t; /* Loop counter */ + uint32 temp; /* Temporary word value */ + uint32 W[80]; /* Word sequence */ + uint32 A, B, C, D, E; /* Word buffers */ int index; - + /* - Initialize the first 16 words in the array W - */ + Initialize the first 16 words in the array W + */ for (t = 0; t < 16; t++) { @@ -322,15 +274,14 @@ void SHA1ProcessMessageBlock(SHA1_CONTEXT *context) for (t = 0; t < 20; t++) { - temp = SHA1CircularShift(5,A) + - ((B & C) | ((~B) & D)) + E + W[t] + K[0]; + temp= SHA1CircularShift(5,A) + ((B & C) | ((~B) & D)) + E + W[t] + K[0]; E = D; D = C; C = SHA1CircularShift(30,B); B = A; A = temp; } - + for (t = 20; t < 40; t++) { temp = SHA1CircularShift(5,A) + (B ^ C ^ D) + E + W[t] + K[1]; @@ -343,8 +294,8 @@ void SHA1ProcessMessageBlock(SHA1_CONTEXT *context) for (t = 40; t < 60; t++) { - temp = SHA1CircularShift(5,A) + - ((B & C) | (B & D) | (C & D)) + E + W[t] + K[2]; + temp= (SHA1CircularShift(5,A) + ((B & C) | (B & D) | (C & D)) + E + W[t] + + K[2]); E = D; D = C; C = SHA1CircularShift(30,B); @@ -367,73 +318,67 @@ void SHA1ProcessMessageBlock(SHA1_CONTEXT *context) context->Intermediate_Hash[2] += C; context->Intermediate_Hash[3] += D; context->Intermediate_Hash[4] += E; - + context->Message_Block_Index = 0; } /* - SHA1PadMessage - - - Description: - According to the standard, the message must be padded to an even - 512 bits. The first padding bit must be a '1'. The last 64 - bits represent the length of the original message. All bits in - between should be 0. This function will pad the message - according to those rules by filling the Message_Block array - accordingly. It will also call the ProcessMessageBlock function - provided appropriately. When it returns, it can be assumed that - the message digest has been computed. - - Parameters: - context: [in/out] - The context to pad - ProcessMessageBlock: [in] - The appropriate SHA*ProcessMessageBlock function - Returns: - Nothing. - + Pad message + + SYNOPSIS + SHA1PadMessage() + context: [in/out] The context to pad + + DESCRIPTION + According to the standard, the message must be padded to an even + 512 bits. The first padding bit must be a '1'. The last 64 bits + represent the length of the original message. All bits in between + should be 0. This function will pad the message according to + those rules by filling the Message_Block array accordingly. It + will also call the ProcessMessageBlock function provided + appropriately. When it returns, it can be assumed that the message + digest has been computed. + */ void SHA1PadMessage(SHA1_CONTEXT *context) { /* - Check to see if the current message block is too small to hold - the initial padding bits and length. If so, we will pad the - block, process it, and then continue padding into a second - block. + Check to see if the current message block is too small to hold + the initial padding bits and length. If so, we will pad the + block, process it, and then continue padding into a second + block. */ - + int i=context->Message_Block_Index; if (i > 55) { context->Message_Block[i++] = 0x80; bzero((char*) &context->Message_Block[i], - sizeof(context->Message_Block[0])*(64-i)); + sizeof(context->Message_Block[0])*(64-i)); context->Message_Block_Index=64; - - /* This function sets context->Message_Block_Index to zero */ - SHA1ProcessMessageBlock(context); + + /* This function sets context->Message_Block_Index to zero */ + SHA1ProcessMessageBlock(context); bzero((char*) &context->Message_Block[0], - sizeof(context->Message_Block[0])*56); + sizeof(context->Message_Block[0])*56); context->Message_Block_Index=56; - - } + } else { context->Message_Block[i++] = 0x80; bzero((char*) &context->Message_Block[i], - sizeof(context->Message_Block[0])*(56-i)); + sizeof(context->Message_Block[0])*(56-i)); context->Message_Block_Index=56; } - + /* - Store the message length as the last 8 octets + Store the message length as the last 8 octets */ - + context->Message_Block[56] = context->Length >> 56; context->Message_Block[57] = context->Length >> 48; context->Message_Block[58] = context->Length >> 40; @@ -445,4 +390,3 @@ void SHA1PadMessage(SHA1_CONTEXT *context) SHA1ProcessMessageBlock(context); } - diff --git a/sql/ha_berkeley.h b/sql/ha_berkeley.h index f56ee5ef1a9..ae425421c70 100644 --- a/sql/ha_berkeley.h +++ b/sql/ha_berkeley.h @@ -88,8 +88,7 @@ class ha_berkeley: public handler ha_berkeley(TABLE *table): handler(table), alloc_ptr(0),rec_buff(0), file(0), int_table_flags(HA_REC_NOT_IN_SEQ | HA_KEYPOS_TO_RNDPOS | HA_LASTKEY_ORDER | - HA_NULL_KEY | HA_HAVE_KEY_READ_ONLY | - HA_BLOB_KEY | HA_NOT_EXACT_COUNT | + HA_NULL_KEY | HA_BLOB_KEY | HA_NOT_EXACT_COUNT | HA_PRIMARY_KEY_IN_READ_INDEX | HA_DROP_BEFORE_CREATE | HA_AUTO_PART_KEY | HA_TABLE_SCAN_ON_INDEX), changed_rows(0),last_dup_key((uint) -1),version(0),using_ignore(0) diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc index 2199547334a..8bb866341b7 100644 --- a/sql/ha_innodb.cc +++ b/sql/ha_innodb.cc @@ -356,13 +356,12 @@ ha_innobase::update_thd( /************************************************************************* Opens an InnoDB database. */ -char current_lib[3]; // Set if using current lib - bool innobase_init(void) /*===============*/ /* out: TRUE if error */ { + static char current_lib[3]; // Set if using current lib int err; bool ret; char *default_path; diff --git a/sql/ha_innodb.h b/sql/ha_innodb.h index b2aa963f91a..4924056f5d2 100644 --- a/sql/ha_innodb.h +++ b/sql/ha_innodb.h @@ -77,7 +77,6 @@ class ha_innobase: public handler ha_innobase(TABLE *table): handler(table), int_table_flags(HA_REC_NOT_IN_SEQ | HA_KEYPOS_TO_RNDPOS | HA_LASTKEY_ORDER | - HA_HAVE_KEY_READ_ONLY | HA_NULL_KEY | HA_NOT_EXACT_COUNT | HA_NO_WRITE_DELAYED | @@ -98,7 +97,7 @@ class ha_innobase: public handler ulong index_flags(uint idx) const { return (HA_READ_NEXT | HA_READ_PREV | HA_READ_ORDER | - HA_NOT_READ_PREFIX_LAST); + HA_NOT_READ_PREFIX_LAST | HA_KEY_READ_ONLY); } uint max_record_length() const { return HA_MAX_REC_LENGTH; } uint max_keys() const { return MAX_KEY; } diff --git a/sql/ha_isam.cc b/sql/ha_isam.cc index 55d24f5edb9..b83dabd86b1 100644 --- a/sql/ha_isam.cc +++ b/sql/ha_isam.cc @@ -51,8 +51,6 @@ int ha_isam::open(const char *name, int mode, uint test_if_locked) info(HA_STATUS_NO_LOCK | HA_STATUS_VARIABLE | HA_STATUS_CONST); if (!(test_if_locked & HA_OPEN_WAIT_IF_LOCKED)) (void) nisam_extra(file,HA_EXTRA_WAIT_LOCK); - if (!table->db_record_offset) - int_table_flags|=HA_REC_NOT_IN_SEQ; return (0); } diff --git a/sql/ha_isam.h b/sql/ha_isam.h index bae9700f149..135424892f5 100644 --- a/sql/ha_isam.h +++ b/sql/ha_isam.h @@ -26,21 +26,20 @@ class ha_isam: public handler { N_INFO *file; - uint int_table_flags; public: - ha_isam(TABLE *table): handler(table), file(0), - int_table_flags(HA_READ_RND_SAME | - HA_KEYPOS_TO_RNDPOS | HA_LASTKEY_ORDER | - HA_HAVE_KEY_READ_ONLY | - HA_KEY_READ_WRONG_STR | HA_DUPP_POS | - HA_NOT_DELETE_WITH_CACHE) - {} + ha_isam(TABLE *table): handler(table), file(0) + {} ~ha_isam() {} const char *table_type() const { return "ISAM"; } const char *index_type(uint key_number) { return "BTREE"; } const char **bas_ext() const; - ulong table_flags() const { return int_table_flags; } + ulong table_flags() const + { + return (HA_READ_RND_SAME | HA_KEYPOS_TO_RNDPOS | HA_LASTKEY_ORDER | + HA_KEY_READ_WRONG_STR | HA_DUPP_POS | HA_NOT_DELETE_WITH_CACHE | + ((table->db_record_offset) ? 0 : HA_REC_NOT_IN_SEQ)); + } uint max_record_length() const { return HA_MAX_REC_LENGTH; } uint max_keys() const { return N_MAXKEY; } uint max_key_parts() const { return N_MAXKEY_SEG; } @@ -80,5 +79,4 @@ class ha_isam: public handler int create(const char *name, TABLE *form, HA_CREATE_INFO *create_info); THR_LOCK_DATA **store_lock(THD *thd, THR_LOCK_DATA **to, enum thr_lock_type lock_type); - }; diff --git a/sql/ha_myisam.cc b/sql/ha_myisam.cc index dc0136b7138..15a85620cd4 100644 --- a/sql/ha_myisam.cc +++ b/sql/ha_myisam.cc @@ -885,7 +885,8 @@ void ha_myisam::info(uint flag) ref_length=info.reflength; table->db_options_in_use = info.options; block_size=myisam_block_size; - table->keys_in_use &= info.key_map; + table->keys_in_use&= info.key_map; + table->keys_for_keyread&= info.key_map; table->db_record_offset=info.record_offset; if (table->key_parts) memcpy((char*) table->key_info[0].rec_per_key, diff --git a/sql/ha_myisam.h b/sql/ha_myisam.h index d304085fdd5..e7f426bb76c 100644 --- a/sql/ha_myisam.h +++ b/sql/ha_myisam.h @@ -45,7 +45,6 @@ class ha_myisam: public handler public: ha_myisam(TABLE *table): handler(table), file(0), int_table_flags(HA_READ_RND_SAME | HA_KEYPOS_TO_RNDPOS | HA_LASTKEY_ORDER | - HA_HAVE_KEY_READ_ONLY | HA_NULL_KEY | HA_CAN_FULLTEXT | HA_CAN_SQL_HANDLER | HA_DUPP_POS | HA_BLOB_KEY | HA_AUTO_PART_KEY), enable_activate_all_index(1) @@ -55,6 +54,12 @@ class ha_myisam: public handler const char *index_type(uint key_number); const char **bas_ext() const; ulong table_flags() const { return int_table_flags; } + ulong index_flags(uint inx) const + { + ulong flags=(HA_READ_NEXT | HA_READ_PREV | HA_READ_ORDER); + return (flags | ((table->key_info[inx].algorithm == HA_KEY_ALG_FULLTEXT) ? + 0 : HA_KEY_READ_ONLY)); + } uint max_record_length() const { return HA_MAX_REC_LENGTH; } uint max_keys() const { return MI_MAX_KEY; } uint max_key_parts() const { return MAX_REF_PARTS; } diff --git a/sql/ha_myisammrg.h b/sql/ha_myisammrg.h index ed2817f3ca6..2b9d7433d2f 100644 --- a/sql/ha_myisammrg.h +++ b/sql/ha_myisammrg.h @@ -35,10 +35,15 @@ class ha_myisammrg: public handler ulong table_flags() const { return (HA_REC_NOT_IN_SEQ | HA_READ_RND_SAME | - HA_HAVE_KEY_READ_ONLY | HA_KEYPOS_TO_RNDPOS | - HA_LASTKEY_ORDER | + HA_KEYPOS_TO_RNDPOS | HA_LASTKEY_ORDER | HA_NULL_KEY | HA_BLOB_KEY); } + ulong index_flags(uint inx) const + { + ulong flags=(HA_READ_NEXT | HA_READ_PREV | HA_READ_ORDER); + return (flags | ((table->key_info[inx].algorithm == HA_KEY_ALG_FULLTEXT) ? + 0 : HA_KEY_READ_ONLY)); + } uint max_record_length() const { return HA_MAX_REC_LENGTH; } uint max_keys() const { return MI_MAX_KEY; } uint max_key_parts() const { return MAX_REF_PARTS; } diff --git a/sql/handler.h b/sql/handler.h index 668453f8905..7984be87058 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -48,7 +48,6 @@ #define HA_TABLE_SCAN_ON_INDEX 4 /* No separate data/index file */ #define HA_REC_NOT_IN_SEQ 8 /* ha_info don't return recnumber; It returns a position to ha_r_rnd */ -#define HA_HAVE_KEY_READ_ONLY 16 /* Can read only keys (no record) */ #define HA_NO_INDEX 32 /* No index needed for next/prev */ #define HA_KEY_READ_WRONG_STR 64 /* keyread returns converted strings */ #define HA_NULL_KEY 128 /* One can have keys with NULL */ @@ -83,6 +82,7 @@ #define HA_READ_ORDER 8 /* Read through record-keys in order */ #define HA_ONLY_WHOLE_INDEX 16 /* Can't use part key searches */ #define HA_NOT_READ_PREFIX_LAST 32 +#define HA_KEY_READ_ONLY 64 /* Support HA_EXTRA_KEYREAD */ /* Parameters for open() (in register form->filestat) @@ -321,7 +321,7 @@ public: virtual ulong table_flags(void) const =0; virtual ulong index_flags(uint idx) const { - return (HA_READ_NEXT | HA_READ_PREV | HA_READ_ORDER); + return (HA_READ_NEXT | HA_READ_PREV | HA_READ_ORDER | HA_KEY_READ_ONLY); } virtual uint max_record_length() const =0; virtual uint max_keys() const =0; diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index fd52668da3f..dfb53a32910 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -153,15 +153,15 @@ String *Item_func_aes_encrypt::val_str(String *str) null_value=0; aes_length=my_aes_get_size(sptr->length()); // calculate result length - if ( !str->alloc(aes_length) ) // Ensure that memory is free + if (!str->alloc(aes_length)) // Ensure that memory is free { // finally encrypt directly to allocated buffer. - if (my_aes_encrypt(sptr->ptr(),sptr->length(),str->ptr(),key->ptr(), - key->length()) == aes_length) + if (my_aes_encrypt(sptr->ptr(),sptr->length(), (char*) str->ptr(), + key->ptr(), key->length()) == aes_length) { - // we have to get expected result length - str->length((uint) aes_length); - return str; + // We got the expected result length + str->length((uint) aes_length); + return str; } } } @@ -169,9 +169,10 @@ String *Item_func_aes_encrypt::val_str(String *str) return 0; } + void Item_func_aes_encrypt::fix_length_and_dec() { - max_length=my_aes_get_size(args[0]->max_length); + max_length=my_aes_get_size(args[0]->max_length); } @@ -184,12 +185,12 @@ String *Item_func_aes_decrypt::val_str(String *str) if (sptr && key) // Need to have both arguments not NULL { null_value=0; - if ( !str->alloc(sptr->length()) ) // Ensure that memory is free + if (!str->alloc(sptr->length())) // Ensure that memory is free { - // finally decencrypt directly to allocated buffer. - length=my_aes_decrypt(sptr->ptr(),sptr->length(),str->ptr(), - key->ptr(),key->length()); - if (length>=0) // if we got correct data data + // finally decrypt directly to allocated buffer. + length=my_aes_decrypt(sptr->ptr(), sptr->length(), (char*) str->ptr(), + key->ptr(), key->length()); + if (length >= 0) // if we got correct data data { str->length((uint) length); return str; @@ -208,9 +209,9 @@ void Item_func_aes_decrypt::fix_length_and_dec() /* -** Concatinate args with the following premissess -** If only one arg which is ok, return value of arg -** Don't reallocate val_str() if not absolute necessary. + Concatenate args with the following premises: + If only one arg (which is ok), return value of arg + Don't reallocate val_str() if not absolute necessary. */ String *Item_func_concat::val_str(String *str) diff --git a/sql/opt_range.cc b/sql/opt_range.cc index 5a359cc4239..33574a81431 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -682,27 +682,27 @@ int SQL_SELECT::test_quick_select(key_map keys_to_use, table_map prev_tables, { ha_rows found_records; double found_read_time; - if (*key) { + uint keynr= param.real_keynr[idx]; if ((*key)->type == SEL_ARG::MAYBE_KEY || (*key)->maybe_flag) - needed_reg|= (key_map) 1 << param.real_keynr[idx]; + needed_reg|= (key_map) 1 << keynr; - found_records=check_quick_select(¶m,idx, *key); + found_records=check_quick_select(¶m, idx, *key); if (found_records != HA_POS_ERROR && found_records > 2 && - head->used_keys & ((table_map) 1 << param.real_keynr[idx]) && - (head->file->table_flags() & HA_HAVE_KEY_READ_ONLY)) + head->used_keys & ((table_map) 1 << keynr) && + (head->file->index_flags(keynr) & HA_KEY_READ_ONLY)) { /* - ** We can resolve this by only reading through this key - ** Assume that we will read trough the whole key range - ** and that all key blocks are half full (normally things are - ** much better) + We can resolve this by only reading through this key. + Assume that we will read trough the whole key range + and that all key blocks are half full (normally things are + much better). */ - uint keys_per_block= head->file->block_size/2/ - (head->key_info[param.real_keynr[idx]].key_length+ - head->file->ref_length) + 1; + uint keys_per_block= (head->file->block_size/2/ + (head->key_info[keynr].key_length+ + head->file->ref_length) + 1); found_read_time=((double) (found_records+keys_per_block-1)/ (double) keys_per_block); } diff --git a/sql/sql_base.cc b/sql/sql_base.cc index d93b40180ee..40f6b40f9b5 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -730,7 +730,8 @@ TABLE *reopen_name_locked_table(THD* thd, TABLE_LIST* table_list) table->const_table=0; table->outer_join=table->null_row=table->maybe_null=0; table->status=STATUS_NO_RECORD; - table->keys_in_use_for_query=table->used_keys= table->keys_in_use; + table->keys_in_use_for_query= table->keys_in_use; + table->used_keys= table->keys_for_keyread; DBUG_RETURN(table); } @@ -884,7 +885,8 @@ TABLE *open_table(THD *thd,const char *db,const char *table_name, table->const_table=0; table->outer_join=table->null_row=table->maybe_null=0; table->status=STATUS_NO_RECORD; - table->keys_in_use_for_query=table->used_keys= table->keys_in_use; + table->keys_in_use_for_query= table->keys_in_use; + table->used_keys= table->keys_for_keyread; DBUG_ASSERT(table->key_read == 0); DBUG_RETURN(table); } @@ -950,7 +952,8 @@ bool reopen_table(TABLE *table,bool locked) tmp.null_row= table->null_row; tmp.maybe_null= table->maybe_null; tmp.status= table->status; - tmp.keys_in_use_for_query=tmp.used_keys=tmp.keys_in_use; + tmp.keys_in_use_for_query= tmp.keys_in_use; + tmp.used_keys= tmp.keys_for_keyread; /* Get state */ tmp.key_length= table->key_length; @@ -1578,7 +1581,7 @@ Field *find_field_in_table(THD *thd,TABLE *table,const char *name,uint length, { field->query_id=thd->query_id; table->used_fields++; - table->used_keys&=field->part_of_key; + table->used_keys&= field->part_of_key; } else thd->dupp_field=field; @@ -1783,7 +1786,8 @@ bool setup_tables(TABLE_LIST *tables) table->const_table=0; table->outer_join=table->null_row=0; table->status=STATUS_NO_RECORD; - table->keys_in_use_for_query=table->used_keys= table->keys_in_use; + table->keys_in_use_for_query= table->keys_in_use; + table->used_keys= table->keys_for_keyread; table->maybe_null=test(table->outer_join=table_list->outer_join); table->tablenr=tablenr; table->map= (table_map) 1 << tablenr; @@ -1873,7 +1877,7 @@ insert_fields(THD *thd,TABLE_LIST *tables, const char *db_name, if (field->query_id == thd->query_id) thd->dupp_field=field; field->query_id=thd->query_id; - table->used_keys&=field->part_of_key; + table->used_keys&= field->part_of_key; } /* All fields are used */ table->used_fields=table->fields; diff --git a/sql/sql_cache.cc b/sql/sql_cache.cc index eb4316efca2..dd38f8fd79b 100644 --- a/sql/sql_cache.cc +++ b/sql/sql_cache.cc @@ -3063,8 +3063,8 @@ my_bool Query_cache::check_integrity(bool not_locked) DBUG_PRINT("qcache", ("block 0x%lx, type %u...", (ulong) block, (uint) block->type)); // Check allignment - if ((((ulonglong)block) % (ulonglong)ALIGN_SIZE(1)) != - (((ulonglong)first_block) % (ulonglong)ALIGN_SIZE(1))) + if ((((long)block) % (long) ALIGN_SIZE(1)) != + (((long)first_block) % (long)ALIGN_SIZE(1))) { DBUG_PRINT("error", ("block 0x%lx do not aligned by %d", (ulong) block, diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 94fa08b769a..0af91c443a8 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -233,7 +233,7 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds, and no GROUP BY. TODO: Add check of calculation of GROUP functions and fields: SELECT COUNT(*)+table.col1 from table1; - */ + */ join.table=0; join.tables=0; { @@ -257,14 +257,7 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds, } TABLE_LIST *table; for (table=tables ; table ; table=table->next) - { join.tables++; - if (!thd->used_tables) - { - TABLE *tbl=table->table; - tbl->keys_in_use_for_query=tbl->used_keys= tbl->keys_in_use=0; - } - } } procedure=setup_procedure(thd,proc_param,result,fields,&error); if (error) diff --git a/sql/table.cc b/sql/table.cc index 5664099adda..9435a83120e 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -133,7 +133,7 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag, if (read_string(file,(gptr*) &disk_buff,key_info_length)) goto err_not_open; /* purecov: inspected */ outparam->keys=keys= disk_buff[0]; - outparam->keys_in_use= set_bits(key_map, keys); + outparam->keys_for_keyread= outparam->keys_in_use= set_bits(key_map, keys); outparam->key_parts=key_parts=disk_buff[1]; n_length=keys*sizeof(KEY)+key_parts*sizeof(KEY_PART_INFO); @@ -199,6 +199,7 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag, for (i=0 ; i < keys ; i++, keyinfo++) keyinfo->algorithm= (enum ha_key_alg) *(strpos++); } + outparam->reclength = uint2korr((head+16)); if (*(head+26) == 1) outparam->system=1; /* one-record-database */ @@ -386,7 +387,17 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag, for (uint key=0 ; key < outparam->keys ; key++,keyinfo++) { uint usable_parts=0; + ulong index_flags; keyinfo->name=(char*) outparam->keynames.type_names[key]; + /* Fix fulltext keys for old .frm files */ + if (outparam->key_info[key].flags & HA_FULLTEXT) + outparam->key_info[key].algorithm= HA_KEY_ALG_FULLTEXT; + + /* This has to be done after the above fulltext correction */ + index_flags=outparam->file->index_flags(key); + if (!(index_flags & HA_KEY_READ_ONLY)) + outparam->keys_for_keyread&= ~((key_map) 1 << key); + if (primary_key >= MAX_KEY && (keyinfo->flags & HA_NOSAME)) { /* @@ -444,7 +455,7 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag, keyinfo->key_length ? UNIQUE_KEY_FLAG : MULTIPLE_KEY_FLAG); if (i == 0) field->key_start|= ((key_map) 1 << key); - if ((ha_option & HA_HAVE_KEY_READ_ONLY) && + if ((index_flags & HA_KEY_READ_ONLY) && field->key_length() == key_part->length && field->type() != FIELD_TYPE_BLOB) { @@ -454,8 +465,7 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag, field->part_of_key|= ((key_map) 1 << key); if ((field->key_type() != HA_KEYTYPE_TEXT || !(keyinfo->flags & HA_FULLTEXT)) && - !(outparam->file->index_flags(key) & - HA_WRONG_ASCII_ORDER)) + !(index_flags & HA_WRONG_ASCII_ORDER)) field->part_of_sortkey|= ((key_map) 1 << key); } if (!(key_part->key_part_flag & HA_REVERSE_SORT) && diff --git a/sql/table.h b/sql/table.h index b6bc3fa8cf1..63b7a9bc2f7 100644 --- a/sql/table.h +++ b/sql/table.h @@ -61,7 +61,8 @@ struct st_table { uint uniques; uint null_fields; /* number of null fields */ uint blob_fields; /* number of blob fields */ - key_map keys_in_use, keys_in_use_for_query; + key_map keys_in_use, keys_for_keyread; + key_map quick_keys, used_keys, keys_in_use_for_query; KEY *key_info; /* data of keys in database */ TYPELIB keynames; /* Pointers to keynames */ ha_rows max_rows; /* create information */ @@ -119,7 +120,6 @@ struct st_table { byte *record_pointers; /* If sorted in memory */ ha_rows found_records; /* How many records in sort */ ORDER *group; - key_map quick_keys, used_keys; ha_rows quick_rows[MAX_KEY]; uint quick_key_parts[MAX_KEY]; key_part_map const_key_parts[MAX_KEY]; |