1 /*
2    Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
3 
4    This program is free software; you can redistribute it and/or modify
5    it under the terms of the GNU General Public License as published by
6    the Free Software Foundation; version 2 of the License.
7 
8    This program is distributed in the hope that it will be useful,
9    but WITHOUT ANY WARRANTY; without even the implied warranty of
10    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11    GNU General Public License for more details.
12 
13    You should have received a copy of the GNU General Public License
14    along with this program; see the file COPYING. If not, write to the
15    Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
16    MA  02110-1301  USA.
17 */
18 
19 /* aes.hpp defines AES
20 */
21 
22 
23 #ifndef TAO_CRYPT_AES_HPP
24 #define TAO_CRYPT_AES_HPP
25 
26 #include "misc.hpp"
27 #include "modes.hpp"
28 
29 
30 #if defined(TAOCRYPT_X86ASM_AVAILABLE) && defined(TAO_ASM)
31     #define DO_AES_ASM
32 #endif
33 
34 
35 
36 namespace TaoCrypt {
37 
38 
39 enum { AES_BLOCK_SIZE = 16 };
40 
41 
42 // AES encryption and decryption, see FIPS-197
43 class AES : public Mode_BASE {
44 public:
45     enum { BLOCK_SIZE = AES_BLOCK_SIZE };
46 
AES(CipherDir DIR,Mode MODE)47     AES(CipherDir DIR, Mode MODE)
48         : Mode_BASE(BLOCK_SIZE, DIR, MODE) {}
49 
50 #ifdef DO_AES_ASM
51     void Process(byte*, const byte*, word32);
52 #endif
53     void SetKey(const byte* key, word32 sz, CipherDir fake = ENCRYPTION);
SetIV(const byte * iv)54     void SetIV(const byte* iv) { memcpy(r_, iv, BLOCK_SIZE); }
55 private:
56     static const word32 rcon_[];
57 
58     word32      rounds_;
59     word32      key_[60];                        // max size
60 
61     static const word32 Te[5][256];
62     static const word32 Td[5][256];
63     static const byte   CTd4[256];
64 
65     static const word32* Te0;
66     static const word32* Te1;
67     static const word32* Te2;
68     static const word32* Te3;
69     static const word32* Te4;
70 
71     static const word32* Td0;
72     static const word32* Td1;
73     static const word32* Td2;
74     static const word32* Td3;
75     static const word32* Td4;
76 
77     void encrypt(const byte*, const byte*, byte*) const;
78     void AsmEncrypt(const byte*, byte*, void*) const;
79     void decrypt(const byte*, const byte*, byte*) const;
80     void AsmDecrypt(const byte*, byte*, void*) const;
81 
82     void ProcessAndXorBlock(const byte*, const byte*, byte*) const;
83 
84     word32 PreFetchTe() const;
85     word32 PreFetchTd() const;
86     word32 PreFetchCTd4() const;
87 
88     AES(const AES&);            // hide copy
89     AES& operator=(const AES&); // and assign
90 };
91 
92 
93 #if defined(__x86_64__) || defined(_M_X64) || \
94            (defined(__ILP32__) && (__ILP32__ >= 1))
95     #define TC_CACHE_LINE_SZ 64
96 #else
97     /* default cache line size */
98     #define TC_CACHE_LINE_SZ 32
99 #endif
100 
PreFetchTe() const101 inline word32 AES::PreFetchTe() const
102 {
103     word32 x = 0;
104 
105     /* 4 tables of 256 entries */
106     for (int i = 0; i < 4; i++) {
107         /* each entry is 4 bytes */
108         for (int j = 0; j < 256; j += TC_CACHE_LINE_SZ/4) {
109             x &= Te[i][j];
110         }
111     }
112 
113     return x;
114 }
115 
116 
PreFetchTd() const117 inline word32 AES::PreFetchTd() const
118 {
119     word32 x = 0;
120 
121     /* 4 tables of 256 entries */
122     for (int i = 0; i < 4; i++) {
123         /* each entry is 4 bytes */
124         for (int j = 0; j < 256; j += TC_CACHE_LINE_SZ/4) {
125             x &= Td[i][j];
126         }
127     }
128 
129     return x;
130 }
131 
132 
PreFetchCTd4() const133 inline word32 AES::PreFetchCTd4() const
134 {
135     word32 x = 0;
136     int i;
137 
138     for (i = 0; i < 256; i += TC_CACHE_LINE_SZ) {
139         x &= CTd4[i];
140     }
141 
142     return x;
143 }
144 
145 
146 typedef BlockCipher<ENCRYPTION, AES, ECB> AES_ECB_Encryption;
147 typedef BlockCipher<DECRYPTION, AES, ECB> AES_ECB_Decryption;
148 
149 typedef BlockCipher<ENCRYPTION, AES, CBC> AES_CBC_Encryption;
150 typedef BlockCipher<DECRYPTION, AES, CBC> AES_CBC_Decryption;
151 
152 
153 } // naemspace
154 
155 #endif // TAO_CRYPT_AES_HPP
156