1 /*===========================================================================
2  *
3  *                            PUBLIC DOMAIN NOTICE
4  *               National Center for Biotechnology Information
5  *
6  *  This software/database is a "United States Government Work" under the
7  *  terms of the United States Copyright Act.  It was written as part of
8  *  the author's official duties as a United States Government employee and
9  *  thus cannot be copyrighted.  This software/database is freely available
10  *  to the public for use. The National Library of Medicine and the U.S.
11  *  Government have not placed any restriction on its use or reproduction.
12  *
13  *  Although all reasonable efforts have been taken to ensure the accuracy
14  *  and reliability of the software and data, the NLM and the U.S.
15  *  Government do not and cannot warrant the performance or results that
16  *  may be obtained by using this software or data. The NLM and the U.S.
17  *  Government disclaim all warranties, express or implied, including
18  *  warranties of performance, merchantability or fitness for any particular
19  *  purpose.
20  *
21  *  Please cite the author in any work or product based on this material.
22  *
23  * ===========================================================================
24  */
25 
26 #ifndef _h_krypto_aes_ncbi_priv_libs_
27 #define _h_krypto_aes_ncbi_priv_libs_
28 
29 #include <klib/defs.h>
30 #include <v128.h>
31 
32 #include "ncbi-priv.h"
33 #include "cipher-impl.h"
34 #include "blockcipher-impl.h"
35 
36 #ifdef  __cplusplus
37 extern "C" {
38 #endif
39 
40 
41 /* ======================================================================
42  * FIPS-197 2.1
43  */
44 #define AES_BLOCK_BITS (128)
45 #define AES_BLOCK_BYTES (AES_BLOCK_BITS/8)
46 
47 
48 /* ======================================================================
49  * FIPS-197 3,4 - 3.5
50  *
51  * FIPS-197 defines Nk as number of 32-bit words in the user key
52  */
53 #define AES_Nk_128 (4)
54 #define AES_Nk_192 (6)
55 #define AES_Nk_256 (8)
56 
57 
58 /*
59  * FIPS-197 defines Nb as number of 32-bit words in the cipher block
60  *
61  * There is much odd naming in the document from the perspective of a software
62  * engineer.
63  */
64 #define AES_Nb (4)
65 #define AES_Nb_128 (AES_Nb)
66 #define AES_Nb_192 (AES_Nb)
67 #define AES_Nb_256 (AES_Nb)
68 
69 
70 /*
71  * FIPS-197 defines Nr as the number of rounds for a cipher of a given original
72  * user key length.
73  *
74  * Another odd naming as it is really the zero based highest round offset
75  * as 1 first round + Nr-1 middle rounds + 1 last round are performed for
76  * each encrypt or decrypt block.  There are thus Nr + 1 round keys needed
77  * in the encryption and decryption key schedules
78  */
79 #define AES_Nr_128 (10)
80 #define AES_Nr_192 (12)
81 #define AES_Nr_256 (14)
82 #define AES_Nr_MAX (15)
83 
84 /* Most useful for testingg against Appendix A-C of the FIPS-197 document */
85 #define DEBUG_OBJECT(msg) DBGMSG(DBG_AES,DBG_FLAG(DBG_AES_OBJECT), msg)
86 #define DEBUG_KEYEXP(msg) DBGMSG(DBG_AES,DBG_FLAG(DBG_AES_KEYEXP), msg)
87 #define DEBUG_CIPHER(msg) DBGMSG(DBG_AES,DBG_FLAG(DBG_AES_CIPHER), msg)
88 #define DEBUG_INVKEYEXP(msg) DBGMSG(DBG_AES,DBG_FLAG(DBG_AES_INVKEYEXP), msg)
89 #define DEBUG_INVCIPHER(msg) DBGMSG(DBG_AES,DBG_FLAG(DBG_AES_INVCIPHER), msg)
90 
91 #define DEBUG_CIPHER_MVECTOR(M,v)                                   \
92     DBGMSG(DBG_AES,DBG_FLAG(DBG_AES_CIPHER),                        \
93            ("%s:\t%0.8x %0.8x %0.8x %0.8x\n",M,                     \
94             v.columns[0],v.columns[1],v.columns[2],v.columns[3]))
95 #define DEBUG_INVCIPHER_MVECTOR(M,v)                                \
96     DBGMSG(DBG_AES,DBG_FLAG(DBG_AES_INVCIPHER),                     \
97            ("%s:\t%0.8x %0.8x %0.8x %0.8x\n",M,                     \
98             v.columns[0],v.columns[1],v.columns[2],v.columns[3]))
99 
100 #if _DEBUGGING
101 #if 1
102 #define DEBUG_CIPHER_VECTOR(M,V)                        \
103     {                                                   \
104         CipherVec_AES_u v; v.state = V;                 \
105         DBGMSG(DBG_AES,DBG_FLAG(DBG_AES_CIPHER),        \
106                ("%s:\t%0.8x %0.8x %0.8x %0.8x\n", M,    \
107                 bswap_32(v.columns[0]),                 \
108                 bswap_32(v.columns[1]),                 \
109                 bswap_32(v.columns[2]),                 \
110                 bswap_32(v.columns[3])));               \
111             }
112 #define DEBUG_INVCIPHER_VECTOR(M,V)                     \
113     {                                                   \
114         CipherVec_AES_u v; v.state = V;                 \
115         DBGMSG(DBG_AES,DBG_FLAG(DBG_AES_INVCIPHER),     \
116                ("%s:\t%0.8x %0.8x %0.8x %0.8x\n", M,    \
117                 bswap_32(v.columns[0]),                 \
118                 bswap_32(v.columns[1]),                 \
119                 bswap_32(v.columns[2]),                 \
120                 bswap_32(v.columns[3])));               \
121             }
122 #else
123 #define DEBUG_CIPHER_VECTOR(M,v)                              \
124     KOutMsg ( "%s:\t%0.8x %0.8x %0.8x %0.8x\n", M,            \
125               bswap_32(((CipherVec_AES_u*)&(v))->columns[0]), \
126               bswap_32(((CipherVec_AES_u*)&(v))->columns[1]), \
127               bswap_32(((CipherVec_AES_u*)&(v))->columns[2]), \
128               bswap_32(((CipherVec_AES_u*)&(v))->columns[3]))
129 #define DEBUG_INVCIPHER_VECTOR(M,v)                           \
130     KOutMsg ( "%s:\t%0.8x %0.8x %0.8x %0.8x\n", M,            \
131               bswap_32(((CipherVec_AES_u*)&(v))->columns[0]), \
132               bswap_32(((CipherVec_AES_u*)&(v))->columns[1]), \
133               bswap_32(((CipherVec_AES_u*)&(v))->columns[2]), \
134               bswap_32(((CipherVec_AES_u*)&(v))->columns[3]))
135 #endif
136 #define DDEBUG_CIPHER_VECTOR(M,v)                             \
137     KOutMsg ( "%s:\t%0.8x %0.8x %0.8x %0.8x\n", M,            \
138               bswap_32(((CipherVec_AES_u*)&(v))->columns[0]), \
139               bswap_32(((CipherVec_AES_u*)&(v))->columns[1]), \
140               bswap_32(((CipherVec_AES_u*)&(v))->columns[2]), \
141               bswap_32(((CipherVec_AES_u*)&(v))->columns[3]))
142 #define DDEBUG_INVCIPHER_VECTOR(M,v)                          \
143     KOutMsg ( "%s:\t%0.8x %0.8x %0.8x %0.8x\n", M,            \
144               bswap_32(((CipherVec_AES_u*)&(v))->columns[0]), \
145               bswap_32(((CipherVec_AES_u*)&(v))->columns[1]), \
146               bswap_32(((CipherVec_AES_u*)&(v))->columns[2]), \
147               bswap_32(((CipherVec_AES_u*)&(v))->columns[3]))
148 
149 #else
150 #define DEBUG_CIPHER_VECTOR(M,V)
151 #define DEBUG_INVCIPHER_VECTOR(M,V)
152 #endif
153 
154 /* -----
155  * 8 and 32 bit unsigned integers
156  */
157 typedef uint8_t  AESByte;
158 typedef uint32_t AESWord;
159 typedef union AESColumn AESColumn;
160 union AESColumn
161 {
162     AESWord word;
163     AESByte bytes [sizeof(AESWord)];
164 };
165 
166 
167 /* -----
168  * 128 byte block in various forms
169  */
170 typedef AESByte AESBlock [AES_Nb*sizeof(AESWord)];
171 
172 typedef v128_u8_t  CipherVecByte;
173 typedef v128_u32_t CipherVecWord;
174 
175 
176 typedef struct AESKeySchedule  AESKeySchedule;
177 struct AESKeySchedule
178 {
179     CipherVec round_keys [AES_Nr_MAX];
180     uint32_t number_of_rounds;
181 };
182 
183 /* ======================================================================
184  * FIPS-197 3,4 - 3.5
185  *
186  * An AES State is the same size as the cipher block size.
187  * They are eaither 4 columns of 32 bits or 16 individual bytes.
188  * The columns can be accessed by their individual bytes s0
189  * there are 4X32, 4X4X8 or 16X8 bits in a state.
190  */
191 typedef union
192 {
193     CipherVec   state;
194     uint64_t    u64     [AES_Nb/2];
195     AESWord     columns [AES_Nb];
196     AESByte     bytes   [AES_Nb * sizeof (AESWord)];
197     AESByte     grid    [AES_Nb][sizeof (AESWord)];
198 } CipherVec_AES_u;
199 
200 
201 typedef union
202 {
203     CipherVec   state;
204     v128_u32_t columns;
205 } CipherVec_uu __attribute__ ((aligned(16)));
206 
207 /*
208  * KCipher with 128 bit alignment.
209  */
210 typedef struct CipherAes CipherAes;
211 struct CipherAes
212 {
213     KCipher dad;
214     AESKeySchedule e_key;
215     AESKeySchedule d_key;
216     CipherVec    e_ivec;
217     CipherVec    d_ivec;
218 };
219 
220 
221 #ifdef  __cplusplus
222 }
223 #endif
224 
225 #endif /* #ifndef _h_krypto_aes_ncbi_priv_libs_ */
226 
227 
228