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