xref: /aosp_15_r20/system/keymaster/key_blob_utils/ocb.c (revision 789431f29546679ab5188a97751fb38e3018d44d)
1*789431f2SAndroid Build Coastguard Worker /*------------------------------------------------------------------------
2*789431f2SAndroid Build Coastguard Worker / OCB Version 3 Reference Code (Optimized C)     Last modified 12-JUN-2013
3*789431f2SAndroid Build Coastguard Worker /-------------------------------------------------------------------------
4*789431f2SAndroid Build Coastguard Worker / Copyright (c) 2013 Ted Krovetz.
5*789431f2SAndroid Build Coastguard Worker /
6*789431f2SAndroid Build Coastguard Worker / Permission to use, copy, modify, and/or distribute this software for any
7*789431f2SAndroid Build Coastguard Worker / purpose with or without fee is hereby granted, provided that the above
8*789431f2SAndroid Build Coastguard Worker / copyright notice and this permission notice appear in all copies.
9*789431f2SAndroid Build Coastguard Worker /
10*789431f2SAndroid Build Coastguard Worker / THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11*789431f2SAndroid Build Coastguard Worker / WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12*789431f2SAndroid Build Coastguard Worker / MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13*789431f2SAndroid Build Coastguard Worker / ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14*789431f2SAndroid Build Coastguard Worker / WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15*789431f2SAndroid Build Coastguard Worker / ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16*789431f2SAndroid Build Coastguard Worker / OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17*789431f2SAndroid Build Coastguard Worker /
18*789431f2SAndroid Build Coastguard Worker / Phillip Rogaway holds patents relevant to OCB. See the following for
19*789431f2SAndroid Build Coastguard Worker / his patent grant: http://www.cs.ucdavis.edu/~rogaway/ocb/grant.htm
20*789431f2SAndroid Build Coastguard Worker /
21*789431f2SAndroid Build Coastguard Worker / Special thanks to Keegan McAllister for suggesting several good improvements
22*789431f2SAndroid Build Coastguard Worker /
23*789431f2SAndroid Build Coastguard Worker / Comments are welcome: Ted Krovetz <[email protected]> - Dedicated to Laurel K
24*789431f2SAndroid Build Coastguard Worker /------------------------------------------------------------------------- */
25*789431f2SAndroid Build Coastguard Worker 
26*789431f2SAndroid Build Coastguard Worker /* ----------------------------------------------------------------------- */
27*789431f2SAndroid Build Coastguard Worker /* Usage notes                                                             */
28*789431f2SAndroid Build Coastguard Worker /* ----------------------------------------------------------------------- */
29*789431f2SAndroid Build Coastguard Worker 
30*789431f2SAndroid Build Coastguard Worker /* - When AE_PENDING is passed as the 'final' parameter of any function,
31*789431f2SAndroid Build Coastguard Worker /    the length parameters must be a multiple of (BPI*16).
32*789431f2SAndroid Build Coastguard Worker /  - When available, SSE or AltiVec registers are used to manipulate data.
33*789431f2SAndroid Build Coastguard Worker /    So, when on machines with these facilities, all pointers passed to
34*789431f2SAndroid Build Coastguard Worker /    any function should be 16-byte aligned.
35*789431f2SAndroid Build Coastguard Worker /  - Plaintext and ciphertext pointers may be equal (ie, plaintext gets
36*789431f2SAndroid Build Coastguard Worker /    encrypted in-place), but no other pair of pointers may be equal.
37*789431f2SAndroid Build Coastguard Worker /  - This code assumes all x86 processors have SSE2 and SSSE3 instructions
38*789431f2SAndroid Build Coastguard Worker /    when compiling under MSVC. If untrue, alter the #define.
39*789431f2SAndroid Build Coastguard Worker /  - This code is tested for C99 and recent versions of GCC and MSVC.      */
40*789431f2SAndroid Build Coastguard Worker 
41*789431f2SAndroid Build Coastguard Worker /* ----------------------------------------------------------------------- */
42*789431f2SAndroid Build Coastguard Worker /* User configuration options                                              */
43*789431f2SAndroid Build Coastguard Worker /* ----------------------------------------------------------------------- */
44*789431f2SAndroid Build Coastguard Worker 
45*789431f2SAndroid Build Coastguard Worker /* Set the AES key length to use and length of authentication tag to produce.
46*789431f2SAndroid Build Coastguard Worker /  Setting either to 0 requires the value be set at runtime via ae_init().
47*789431f2SAndroid Build Coastguard Worker /  Some optimizations occur for each when set to a fixed value.            */
48*789431f2SAndroid Build Coastguard Worker #define OCB_KEY_LEN 16 /* 0, 16, 24 or 32. 0 means set in ae_init */
49*789431f2SAndroid Build Coastguard Worker #define OCB_TAG_LEN 16 /* 0 to 16. 0 means set in ae_init         */
50*789431f2SAndroid Build Coastguard Worker 
51*789431f2SAndroid Build Coastguard Worker /* This implementation has built-in support for multiple AES APIs. Set any
52*789431f2SAndroid Build Coastguard Worker /  one of the following to non-zero to specify which to use.               */
53*789431f2SAndroid Build Coastguard Worker #define USE_OPENSSL_AES 1   /* http://openssl.org                      */
54*789431f2SAndroid Build Coastguard Worker #define USE_REFERENCE_AES 0 /* Internet search: rijndael-alg-fst.c     */
55*789431f2SAndroid Build Coastguard Worker #define USE_AES_NI 0        /* Uses compiler's intrinsics              */
56*789431f2SAndroid Build Coastguard Worker 
57*789431f2SAndroid Build Coastguard Worker /* During encryption and decryption, various "L values" are required.
58*789431f2SAndroid Build Coastguard Worker /  The L values can be precomputed during initialization (requiring extra
59*789431f2SAndroid Build Coastguard Worker /  space in ae_ctx), generated as needed (slightly slowing encryption and
60*789431f2SAndroid Build Coastguard Worker /  decryption), or some combination of the two. L_TABLE_SZ specifies how many
61*789431f2SAndroid Build Coastguard Worker /  L values to precompute. L_TABLE_SZ must be at least 3. L_TABLE_SZ*16 bytes
62*789431f2SAndroid Build Coastguard Worker /  are used for L values in ae_ctx. Plaintext and ciphertexts shorter than
63*789431f2SAndroid Build Coastguard Worker /  2^L_TABLE_SZ blocks need no L values calculated dynamically.            */
64*789431f2SAndroid Build Coastguard Worker #define L_TABLE_SZ 16
65*789431f2SAndroid Build Coastguard Worker 
66*789431f2SAndroid Build Coastguard Worker /* Set L_TABLE_SZ_IS_ENOUGH non-zero iff you know that all plaintexts
67*789431f2SAndroid Build Coastguard Worker /  will be shorter than 2^(L_TABLE_SZ+4) bytes in length. This results
68*789431f2SAndroid Build Coastguard Worker /  in better performance.                                                  */
69*789431f2SAndroid Build Coastguard Worker #define L_TABLE_SZ_IS_ENOUGH 1
70*789431f2SAndroid Build Coastguard Worker 
71*789431f2SAndroid Build Coastguard Worker /* ----------------------------------------------------------------------- */
72*789431f2SAndroid Build Coastguard Worker /* Includes and compiler specific definitions                              */
73*789431f2SAndroid Build Coastguard Worker /* ----------------------------------------------------------------------- */
74*789431f2SAndroid Build Coastguard Worker 
75*789431f2SAndroid Build Coastguard Worker #include <keymaster/key_blob_utils/ae.h>
76*789431f2SAndroid Build Coastguard Worker #include <stdlib.h>
77*789431f2SAndroid Build Coastguard Worker #include <string.h>
78*789431f2SAndroid Build Coastguard Worker 
79*789431f2SAndroid Build Coastguard Worker /* Define standard sized integers                                          */
80*789431f2SAndroid Build Coastguard Worker #if defined(_MSC_VER) && (_MSC_VER < 1600)
81*789431f2SAndroid Build Coastguard Worker typedef unsigned __int8 uint8_t;
82*789431f2SAndroid Build Coastguard Worker typedef unsigned __int32 uint32_t;
83*789431f2SAndroid Build Coastguard Worker typedef unsigned __int64 uint64_t;
84*789431f2SAndroid Build Coastguard Worker typedef __int64 int64_t;
85*789431f2SAndroid Build Coastguard Worker #else
86*789431f2SAndroid Build Coastguard Worker #include <stdint.h>
87*789431f2SAndroid Build Coastguard Worker #endif
88*789431f2SAndroid Build Coastguard Worker 
89*789431f2SAndroid Build Coastguard Worker /* Compiler-specific intrinsics and fixes: bswap64, ntz                    */
90*789431f2SAndroid Build Coastguard Worker #if _MSC_VER
91*789431f2SAndroid Build Coastguard Worker #define inline __inline                           /* MSVC doesn't recognize "inline" in C */
92*789431f2SAndroid Build Coastguard Worker #define restrict __restrict                       /* MSVC doesn't recognize "restrict" in C */
93*789431f2SAndroid Build Coastguard Worker #define __SSE2__ (_M_IX86 || _M_AMD64 || _M_X64)  /* Assume SSE2  */
94*789431f2SAndroid Build Coastguard Worker #define __SSSE3__ (_M_IX86 || _M_AMD64 || _M_X64) /* Assume SSSE3 */
95*789431f2SAndroid Build Coastguard Worker #include <intrin.h>
96*789431f2SAndroid Build Coastguard Worker #pragma intrinsic(_byteswap_uint64, _BitScanForward, memcpy)
97*789431f2SAndroid Build Coastguard Worker #define bswap64(x) _byteswap_uint64(x)
ntz(unsigned x)98*789431f2SAndroid Build Coastguard Worker static inline unsigned ntz(unsigned x) {
99*789431f2SAndroid Build Coastguard Worker     _BitScanForward(&x, x);
100*789431f2SAndroid Build Coastguard Worker     return x;
101*789431f2SAndroid Build Coastguard Worker }
102*789431f2SAndroid Build Coastguard Worker #elif __GNUC__
103*789431f2SAndroid Build Coastguard Worker #define inline __inline__                   /* No "inline" in GCC ansi C mode */
104*789431f2SAndroid Build Coastguard Worker #define restrict __restrict__               /* No "restrict" in GCC ansi C mode */
105*789431f2SAndroid Build Coastguard Worker #define bswap64(x) __builtin_bswap64(x)     /* Assuming GCC 4.3+ */
106*789431f2SAndroid Build Coastguard Worker #define ntz(x) __builtin_ctz((unsigned)(x)) /* Assuming GCC 3.4+ */
107*789431f2SAndroid Build Coastguard Worker #else /* Assume some C99 features: stdint.h, inline, restrict */
108*789431f2SAndroid Build Coastguard Worker #define bswap32(x)                                                                                 \
109*789431f2SAndroid Build Coastguard Worker     ((((x)&0xff000000u) >> 24) | (((x)&0x00ff0000u) >> 8) | (((x)&0x0000ff00u) << 8) |             \
110*789431f2SAndroid Build Coastguard Worker      (((x)&0x000000ffu) << 24))
111*789431f2SAndroid Build Coastguard Worker 
bswap64(uint64_t x)112*789431f2SAndroid Build Coastguard Worker static inline uint64_t bswap64(uint64_t x) {
113*789431f2SAndroid Build Coastguard Worker     union {
114*789431f2SAndroid Build Coastguard Worker         uint64_t u64;
115*789431f2SAndroid Build Coastguard Worker         uint32_t u32[2];
116*789431f2SAndroid Build Coastguard Worker     } in, out;
117*789431f2SAndroid Build Coastguard Worker     in.u64 = x;
118*789431f2SAndroid Build Coastguard Worker     out.u32[0] = bswap32(in.u32[1]);
119*789431f2SAndroid Build Coastguard Worker     out.u32[1] = bswap32(in.u32[0]);
120*789431f2SAndroid Build Coastguard Worker     return out.u64;
121*789431f2SAndroid Build Coastguard Worker }
122*789431f2SAndroid Build Coastguard Worker 
123*789431f2SAndroid Build Coastguard Worker #if (L_TABLE_SZ <= 9) && (L_TABLE_SZ_IS_ENOUGH) /* < 2^13 byte texts */
ntz(unsigned x)124*789431f2SAndroid Build Coastguard Worker static inline unsigned ntz(unsigned x) {
125*789431f2SAndroid Build Coastguard Worker     static const unsigned char tz_table[] = {
126*789431f2SAndroid Build Coastguard Worker         0, 2, 3, 2, 4, 2, 3, 2, 5, 2, 3, 2, 4, 2, 3, 2, 6, 2, 3, 2, 4, 2, 3, 2, 5, 2,
127*789431f2SAndroid Build Coastguard Worker         3, 2, 4, 2, 3, 2, 7, 2, 3, 2, 4, 2, 3, 2, 5, 2, 3, 2, 4, 2, 3, 2, 6, 2, 3, 2,
128*789431f2SAndroid Build Coastguard Worker         4, 2, 3, 2, 5, 2, 3, 2, 4, 2, 3, 2, 8, 2, 3, 2, 4, 2, 3, 2, 5, 2, 3, 2, 4, 2,
129*789431f2SAndroid Build Coastguard Worker         3, 2, 6, 2, 3, 2, 4, 2, 3, 2, 5, 2, 3, 2, 4, 2, 3, 2, 7, 2, 3, 2, 4, 2, 3, 2,
130*789431f2SAndroid Build Coastguard Worker         5, 2, 3, 2, 4, 2, 3, 2, 6, 2, 3, 2, 4, 2, 3, 2, 5, 2, 3, 2, 4, 2, 3, 2};
131*789431f2SAndroid Build Coastguard Worker     return tz_table[x / 4];
132*789431f2SAndroid Build Coastguard Worker }
133*789431f2SAndroid Build Coastguard Worker #else                                           /* From http://supertech.csail.mit.edu/papers/debruijn.pdf */
ntz(unsigned x)134*789431f2SAndroid Build Coastguard Worker static inline unsigned ntz(unsigned x) {
135*789431f2SAndroid Build Coastguard Worker     static const unsigned char tz_table[32] = {0,  1,  28, 2,  29, 14, 24, 3,  30, 22, 20,
136*789431f2SAndroid Build Coastguard Worker                                                15, 25, 17, 4,  8,  31, 27, 13, 23, 21, 19,
137*789431f2SAndroid Build Coastguard Worker                                                16, 7,  26, 12, 18, 6,  11, 5,  10, 9};
138*789431f2SAndroid Build Coastguard Worker     return tz_table[((uint32_t)((x & -x) * 0x077CB531u)) >> 27];
139*789431f2SAndroid Build Coastguard Worker }
140*789431f2SAndroid Build Coastguard Worker #endif
141*789431f2SAndroid Build Coastguard Worker #endif
142*789431f2SAndroid Build Coastguard Worker 
143*789431f2SAndroid Build Coastguard Worker /* ----------------------------------------------------------------------- */
144*789431f2SAndroid Build Coastguard Worker /* Define blocks and operations -- Patch if incorrect on your compiler.    */
145*789431f2SAndroid Build Coastguard Worker /* ----------------------------------------------------------------------- */
146*789431f2SAndroid Build Coastguard Worker 
147*789431f2SAndroid Build Coastguard Worker #if __SSE2__ && !KEYMASTER_CLANG_TEST_BUILD
148*789431f2SAndroid Build Coastguard Worker #include <xmmintrin.h> /* SSE instructions and _mm_malloc */
149*789431f2SAndroid Build Coastguard Worker #include <emmintrin.h> /* SSE2 instructions               */
150*789431f2SAndroid Build Coastguard Worker typedef __m128i block;
151*789431f2SAndroid Build Coastguard Worker #define xor_block(x, y) _mm_xor_si128(x, y)
152*789431f2SAndroid Build Coastguard Worker #define zero_block() _mm_setzero_si128()
153*789431f2SAndroid Build Coastguard Worker #define unequal_blocks(x, y) (_mm_movemask_epi8(_mm_cmpeq_epi8(x, y)) != 0xffff)
154*789431f2SAndroid Build Coastguard Worker #if __SSSE3__ || USE_AES_NI
155*789431f2SAndroid Build Coastguard Worker #include <tmmintrin.h> /* SSSE3 instructions              */
156*789431f2SAndroid Build Coastguard Worker #define swap_if_le(b)                                                                              \
157*789431f2SAndroid Build Coastguard Worker     _mm_shuffle_epi8(b, _mm_set_epi8(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15))
158*789431f2SAndroid Build Coastguard Worker #else
swap_if_le(block b)159*789431f2SAndroid Build Coastguard Worker static inline block swap_if_le(block b) {
160*789431f2SAndroid Build Coastguard Worker     block a = _mm_shuffle_epi32(b, _MM_SHUFFLE(0, 1, 2, 3));
161*789431f2SAndroid Build Coastguard Worker     a = _mm_shufflehi_epi16(a, _MM_SHUFFLE(2, 3, 0, 1));
162*789431f2SAndroid Build Coastguard Worker     a = _mm_shufflelo_epi16(a, _MM_SHUFFLE(2, 3, 0, 1));
163*789431f2SAndroid Build Coastguard Worker     return _mm_xor_si128(_mm_srli_epi16(a, 8), _mm_slli_epi16(a, 8));
164*789431f2SAndroid Build Coastguard Worker }
165*789431f2SAndroid Build Coastguard Worker #endif
gen_offset(uint64_t KtopStr[3],unsigned bot)166*789431f2SAndroid Build Coastguard Worker static inline block gen_offset(uint64_t KtopStr[3], unsigned bot) {
167*789431f2SAndroid Build Coastguard Worker     block hi = _mm_load_si128((__m128i*)(KtopStr + 0));  /* hi = B A */
168*789431f2SAndroid Build Coastguard Worker     block lo = _mm_loadu_si128((__m128i*)(KtopStr + 1)); /* lo = C B */
169*789431f2SAndroid Build Coastguard Worker     __m128i lshift = _mm_cvtsi32_si128(bot);
170*789431f2SAndroid Build Coastguard Worker     __m128i rshift = _mm_cvtsi32_si128(64 - bot);
171*789431f2SAndroid Build Coastguard Worker     lo = _mm_xor_si128(_mm_sll_epi64(hi, lshift), _mm_srl_epi64(lo, rshift));
172*789431f2SAndroid Build Coastguard Worker #if __SSSE3__ || USE_AES_NI
173*789431f2SAndroid Build Coastguard Worker     return _mm_shuffle_epi8(lo, _mm_set_epi8(8, 9, 10, 11, 12, 13, 14, 15, 0, 1, 2, 3, 4, 5, 6, 7));
174*789431f2SAndroid Build Coastguard Worker #else
175*789431f2SAndroid Build Coastguard Worker     return swap_if_le(_mm_shuffle_epi32(lo, _MM_SHUFFLE(1, 0, 3, 2)));
176*789431f2SAndroid Build Coastguard Worker #endif
177*789431f2SAndroid Build Coastguard Worker }
double_block(block bl)178*789431f2SAndroid Build Coastguard Worker static inline block double_block(block bl) {
179*789431f2SAndroid Build Coastguard Worker     const __m128i mask = _mm_set_epi32(135, 1, 1, 1);
180*789431f2SAndroid Build Coastguard Worker     __m128i tmp = _mm_srai_epi32(bl, 31);
181*789431f2SAndroid Build Coastguard Worker     tmp = _mm_and_si128(tmp, mask);
182*789431f2SAndroid Build Coastguard Worker     tmp = _mm_shuffle_epi32(tmp, _MM_SHUFFLE(2, 1, 0, 3));
183*789431f2SAndroid Build Coastguard Worker     bl = _mm_slli_epi32(bl, 1);
184*789431f2SAndroid Build Coastguard Worker     return _mm_xor_si128(bl, tmp);
185*789431f2SAndroid Build Coastguard Worker }
186*789431f2SAndroid Build Coastguard Worker #elif __ALTIVEC__
187*789431f2SAndroid Build Coastguard Worker #include <altivec.h>
188*789431f2SAndroid Build Coastguard Worker typedef vector unsigned block;
189*789431f2SAndroid Build Coastguard Worker #define xor_block(x, y) vec_xor(x, y)
190*789431f2SAndroid Build Coastguard Worker #define zero_block() vec_splat_u32(0)
191*789431f2SAndroid Build Coastguard Worker #define unequal_blocks(x, y) vec_any_ne(x, y)
192*789431f2SAndroid Build Coastguard Worker #define swap_if_le(b) (b)
193*789431f2SAndroid Build Coastguard Worker #if __PPC64__
gen_offset(uint64_t KtopStr[3],unsigned bot)194*789431f2SAndroid Build Coastguard Worker block gen_offset(uint64_t KtopStr[3], unsigned bot) {
195*789431f2SAndroid Build Coastguard Worker     union {
196*789431f2SAndroid Build Coastguard Worker         uint64_t u64[2];
197*789431f2SAndroid Build Coastguard Worker         block bl;
198*789431f2SAndroid Build Coastguard Worker     } rval;
199*789431f2SAndroid Build Coastguard Worker     rval.u64[0] = (KtopStr[0] << bot) | (KtopStr[1] >> (64 - bot));
200*789431f2SAndroid Build Coastguard Worker     rval.u64[1] = (KtopStr[1] << bot) | (KtopStr[2] >> (64 - bot));
201*789431f2SAndroid Build Coastguard Worker     return rval.bl;
202*789431f2SAndroid Build Coastguard Worker }
203*789431f2SAndroid Build Coastguard Worker #else
204*789431f2SAndroid Build Coastguard Worker /* Special handling: Shifts are mod 32, and no 64-bit types */
gen_offset(uint64_t KtopStr[3],unsigned bot)205*789431f2SAndroid Build Coastguard Worker block gen_offset(uint64_t KtopStr[3], unsigned bot) {
206*789431f2SAndroid Build Coastguard Worker     const vector unsigned k32 = {32, 32, 32, 32};
207*789431f2SAndroid Build Coastguard Worker     vector unsigned hi = *(vector unsigned*)(KtopStr + 0);
208*789431f2SAndroid Build Coastguard Worker     vector unsigned lo = *(vector unsigned*)(KtopStr + 2);
209*789431f2SAndroid Build Coastguard Worker     vector unsigned bot_vec;
210*789431f2SAndroid Build Coastguard Worker     if (bot < 32) {
211*789431f2SAndroid Build Coastguard Worker         lo = vec_sld(hi, lo, 4);
212*789431f2SAndroid Build Coastguard Worker     } else {
213*789431f2SAndroid Build Coastguard Worker         vector unsigned t = vec_sld(hi, lo, 4);
214*789431f2SAndroid Build Coastguard Worker         lo = vec_sld(hi, lo, 8);
215*789431f2SAndroid Build Coastguard Worker         hi = t;
216*789431f2SAndroid Build Coastguard Worker         bot = bot - 32;
217*789431f2SAndroid Build Coastguard Worker     }
218*789431f2SAndroid Build Coastguard Worker     if (bot == 0)
219*789431f2SAndroid Build Coastguard Worker         return hi;
220*789431f2SAndroid Build Coastguard Worker     *(unsigned*)&bot_vec = bot;
221*789431f2SAndroid Build Coastguard Worker     vector unsigned lshift = vec_splat(bot_vec, 0);
222*789431f2SAndroid Build Coastguard Worker     vector unsigned rshift = vec_sub(k32, lshift);
223*789431f2SAndroid Build Coastguard Worker     hi = vec_sl(hi, lshift);
224*789431f2SAndroid Build Coastguard Worker     lo = vec_sr(lo, rshift);
225*789431f2SAndroid Build Coastguard Worker     return vec_xor(hi, lo);
226*789431f2SAndroid Build Coastguard Worker }
227*789431f2SAndroid Build Coastguard Worker #endif
double_block(block b)228*789431f2SAndroid Build Coastguard Worker static inline block double_block(block b) {
229*789431f2SAndroid Build Coastguard Worker     const vector unsigned char mask = {135, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1};
230*789431f2SAndroid Build Coastguard Worker     const vector unsigned char perm = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0};
231*789431f2SAndroid Build Coastguard Worker     const vector unsigned char shift7 = vec_splat_u8(7);
232*789431f2SAndroid Build Coastguard Worker     const vector unsigned char shift1 = vec_splat_u8(1);
233*789431f2SAndroid Build Coastguard Worker     vector unsigned char c = (vector unsigned char)b;
234*789431f2SAndroid Build Coastguard Worker     vector unsigned char t = vec_sra(c, shift7);
235*789431f2SAndroid Build Coastguard Worker     t = vec_and(t, mask);
236*789431f2SAndroid Build Coastguard Worker     t = vec_perm(t, t, perm);
237*789431f2SAndroid Build Coastguard Worker     c = vec_sl(c, shift1);
238*789431f2SAndroid Build Coastguard Worker     return (block)vec_xor(c, t);
239*789431f2SAndroid Build Coastguard Worker }
240*789431f2SAndroid Build Coastguard Worker #elif __ARM_NEON__
241*789431f2SAndroid Build Coastguard Worker #include <arm_neon.h>
242*789431f2SAndroid Build Coastguard Worker typedef int8x16_t block __attribute__ ((aligned (16))); /* Yay! Endian-neutral reads! */
243*789431f2SAndroid Build Coastguard Worker #define xor_block(x, y) veorq_s8(x, y)
244*789431f2SAndroid Build Coastguard Worker #define zero_block() vdupq_n_s8(0)
unequal_blocks(block a,block b)245*789431f2SAndroid Build Coastguard Worker static inline int unequal_blocks(block a, block b) {
246*789431f2SAndroid Build Coastguard Worker     int64x2_t t = veorq_s64((int64x2_t)a, (int64x2_t)b);
247*789431f2SAndroid Build Coastguard Worker     return (vgetq_lane_s64(t, 0) | vgetq_lane_s64(t, 1)) != 0;
248*789431f2SAndroid Build Coastguard Worker }
249*789431f2SAndroid Build Coastguard Worker #define swap_if_le(b) (b) /* Using endian-neutral int8x16_t */
250*789431f2SAndroid Build Coastguard Worker /* KtopStr is reg correct by 64 bits, return mem correct */
gen_offset(uint64_t KtopStr[3],unsigned bot)251*789431f2SAndroid Build Coastguard Worker block gen_offset(uint64_t KtopStr[3], unsigned bot) {
252*789431f2SAndroid Build Coastguard Worker     const union {
253*789431f2SAndroid Build Coastguard Worker         unsigned x;
254*789431f2SAndroid Build Coastguard Worker         unsigned char endian;
255*789431f2SAndroid Build Coastguard Worker     } little = {1};
256*789431f2SAndroid Build Coastguard Worker     const int64x2_t k64 = {-64, -64};
257*789431f2SAndroid Build Coastguard Worker     /* Copy hi and lo into local variables to ensure proper alignment */
258*789431f2SAndroid Build Coastguard Worker     uint64x2_t hi = vld1q_u64(KtopStr + 0); /* hi = A B */
259*789431f2SAndroid Build Coastguard Worker     uint64x2_t lo = vld1q_u64(KtopStr + 1); /* lo = B C */
260*789431f2SAndroid Build Coastguard Worker     int64x2_t ls = vdupq_n_s64(bot);
261*789431f2SAndroid Build Coastguard Worker     int64x2_t rs = vqaddq_s64(k64, ls);
262*789431f2SAndroid Build Coastguard Worker     block rval = (block)veorq_u64(vshlq_u64(hi, ls), vshlq_u64(lo, rs));
263*789431f2SAndroid Build Coastguard Worker     if (little.endian)
264*789431f2SAndroid Build Coastguard Worker         rval = vrev64q_s8(rval);
265*789431f2SAndroid Build Coastguard Worker     return rval;
266*789431f2SAndroid Build Coastguard Worker }
double_block(block b)267*789431f2SAndroid Build Coastguard Worker static inline block double_block(block b) {
268*789431f2SAndroid Build Coastguard Worker     const block mask = {135, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1};
269*789431f2SAndroid Build Coastguard Worker     block tmp = vshrq_n_s8(b, 7);
270*789431f2SAndroid Build Coastguard Worker     tmp = vandq_s8(tmp, mask);
271*789431f2SAndroid Build Coastguard Worker     tmp = vextq_s8(tmp, tmp, 1); /* Rotate high byte to end */
272*789431f2SAndroid Build Coastguard Worker     b = vshlq_n_s8(b, 1);
273*789431f2SAndroid Build Coastguard Worker     return veorq_s8(tmp, b);
274*789431f2SAndroid Build Coastguard Worker }
275*789431f2SAndroid Build Coastguard Worker #else
276*789431f2SAndroid Build Coastguard Worker typedef struct { uint64_t l, r; } block;
xor_block(block x,block y)277*789431f2SAndroid Build Coastguard Worker static inline block xor_block(block x, block y) {
278*789431f2SAndroid Build Coastguard Worker     x.l ^= y.l;
279*789431f2SAndroid Build Coastguard Worker     x.r ^= y.r;
280*789431f2SAndroid Build Coastguard Worker     return x;
281*789431f2SAndroid Build Coastguard Worker }
zero_block(void)282*789431f2SAndroid Build Coastguard Worker static inline block zero_block(void) {
283*789431f2SAndroid Build Coastguard Worker     const block t = {0, 0};
284*789431f2SAndroid Build Coastguard Worker     return t;
285*789431f2SAndroid Build Coastguard Worker }
286*789431f2SAndroid Build Coastguard Worker #define unequal_blocks(x, y) ((((x).l ^ (y).l) | ((x).r ^ (y).r)) != 0)
swap_if_le(block b)287*789431f2SAndroid Build Coastguard Worker static inline block swap_if_le(block b) {
288*789431f2SAndroid Build Coastguard Worker     const union {
289*789431f2SAndroid Build Coastguard Worker         unsigned x;
290*789431f2SAndroid Build Coastguard Worker         unsigned char endian;
291*789431f2SAndroid Build Coastguard Worker     } little = {1};
292*789431f2SAndroid Build Coastguard Worker     if (little.endian) {
293*789431f2SAndroid Build Coastguard Worker         block r;
294*789431f2SAndroid Build Coastguard Worker         r.l = bswap64(b.l);
295*789431f2SAndroid Build Coastguard Worker         r.r = bswap64(b.r);
296*789431f2SAndroid Build Coastguard Worker         return r;
297*789431f2SAndroid Build Coastguard Worker     } else
298*789431f2SAndroid Build Coastguard Worker         return b;
299*789431f2SAndroid Build Coastguard Worker }
300*789431f2SAndroid Build Coastguard Worker 
301*789431f2SAndroid Build Coastguard Worker /* KtopStr is reg correct by 64 bits, return mem correct */
gen_offset(uint64_t KtopStr[3],unsigned bot)302*789431f2SAndroid Build Coastguard Worker block gen_offset(uint64_t KtopStr[3], unsigned bot) {
303*789431f2SAndroid Build Coastguard Worker     block rval;
304*789431f2SAndroid Build Coastguard Worker     if (bot != 0) {
305*789431f2SAndroid Build Coastguard Worker         rval.l = (KtopStr[0] << bot) | (KtopStr[1] >> (64 - bot));
306*789431f2SAndroid Build Coastguard Worker         rval.r = (KtopStr[1] << bot) | (KtopStr[2] >> (64 - bot));
307*789431f2SAndroid Build Coastguard Worker     } else {
308*789431f2SAndroid Build Coastguard Worker         rval.l = KtopStr[0];
309*789431f2SAndroid Build Coastguard Worker         rval.r = KtopStr[1];
310*789431f2SAndroid Build Coastguard Worker     }
311*789431f2SAndroid Build Coastguard Worker     return swap_if_le(rval);
312*789431f2SAndroid Build Coastguard Worker }
313*789431f2SAndroid Build Coastguard Worker 
314*789431f2SAndroid Build Coastguard Worker #if __GNUC__ && __arm__
double_block(block b)315*789431f2SAndroid Build Coastguard Worker static inline block double_block(block b) {
316*789431f2SAndroid Build Coastguard Worker     __asm__("adds %1,%1,%1\n\t"
317*789431f2SAndroid Build Coastguard Worker             "adcs %H1,%H1,%H1\n\t"
318*789431f2SAndroid Build Coastguard Worker             "adcs %0,%0,%0\n\t"
319*789431f2SAndroid Build Coastguard Worker             "adcs %H0,%H0,%H0\n\t"
320*789431f2SAndroid Build Coastguard Worker             "it cs\n\t"
321*789431f2SAndroid Build Coastguard Worker             "eorcs %1,%1,#135"
322*789431f2SAndroid Build Coastguard Worker             : "+r"(b.l), "+r"(b.r)
323*789431f2SAndroid Build Coastguard Worker             :
324*789431f2SAndroid Build Coastguard Worker             : "cc");
325*789431f2SAndroid Build Coastguard Worker     return b;
326*789431f2SAndroid Build Coastguard Worker }
327*789431f2SAndroid Build Coastguard Worker #else
double_block(block b)328*789431f2SAndroid Build Coastguard Worker static inline block double_block(block b) {
329*789431f2SAndroid Build Coastguard Worker     uint64_t t = (uint64_t)((int64_t)b.l >> 63);
330*789431f2SAndroid Build Coastguard Worker     b.l = (b.l + b.l) ^ (b.r >> 63);
331*789431f2SAndroid Build Coastguard Worker     b.r = (b.r + b.r) ^ (t & 135);
332*789431f2SAndroid Build Coastguard Worker     return b;
333*789431f2SAndroid Build Coastguard Worker }
334*789431f2SAndroid Build Coastguard Worker #endif
335*789431f2SAndroid Build Coastguard Worker 
336*789431f2SAndroid Build Coastguard Worker #endif
337*789431f2SAndroid Build Coastguard Worker 
338*789431f2SAndroid Build Coastguard Worker #ifndef __has_attribute
339*789431f2SAndroid Build Coastguard Worker #define __has_attribute(x) 0
340*789431f2SAndroid Build Coastguard Worker #endif
341*789431f2SAndroid Build Coastguard Worker 
342*789431f2SAndroid Build Coastguard Worker #if __has_attribute(fallthrough)
343*789431f2SAndroid Build Coastguard Worker #define __fallthrough __attribute__((__fallthrough__));
344*789431f2SAndroid Build Coastguard Worker #else
345*789431f2SAndroid Build Coastguard Worker #define __fallthrough
346*789431f2SAndroid Build Coastguard Worker #endif
347*789431f2SAndroid Build Coastguard Worker 
348*789431f2SAndroid Build Coastguard Worker /* ----------------------------------------------------------------------- */
349*789431f2SAndroid Build Coastguard Worker /* AES - Code uses OpenSSL API. Other implementations get mapped to it.    */
350*789431f2SAndroid Build Coastguard Worker /* ----------------------------------------------------------------------- */
351*789431f2SAndroid Build Coastguard Worker 
352*789431f2SAndroid Build Coastguard Worker /*---------------*/
353*789431f2SAndroid Build Coastguard Worker #if USE_OPENSSL_AES
354*789431f2SAndroid Build Coastguard Worker /*---------------*/
355*789431f2SAndroid Build Coastguard Worker 
356*789431f2SAndroid Build Coastguard Worker #include <openssl/aes.h> /* http://openssl.org/ */
357*789431f2SAndroid Build Coastguard Worker 
358*789431f2SAndroid Build Coastguard Worker /* How to ECB encrypt an array of blocks, in place                         */
AES_ecb_encrypt_blks(block * blks,unsigned nblks,AES_KEY * key)359*789431f2SAndroid Build Coastguard Worker static inline void AES_ecb_encrypt_blks(block* blks, unsigned nblks, AES_KEY* key) {
360*789431f2SAndroid Build Coastguard Worker     while (nblks) {
361*789431f2SAndroid Build Coastguard Worker         --nblks;
362*789431f2SAndroid Build Coastguard Worker         AES_encrypt((unsigned char*)(blks + nblks), (unsigned char*)(blks + nblks), key);
363*789431f2SAndroid Build Coastguard Worker     }
364*789431f2SAndroid Build Coastguard Worker }
365*789431f2SAndroid Build Coastguard Worker 
AES_ecb_decrypt_blks(block * blks,unsigned nblks,AES_KEY * key)366*789431f2SAndroid Build Coastguard Worker static inline void AES_ecb_decrypt_blks(block* blks, unsigned nblks, AES_KEY* key) {
367*789431f2SAndroid Build Coastguard Worker     while (nblks) {
368*789431f2SAndroid Build Coastguard Worker         --nblks;
369*789431f2SAndroid Build Coastguard Worker         AES_decrypt((unsigned char*)(blks + nblks), (unsigned char*)(blks + nblks), key);
370*789431f2SAndroid Build Coastguard Worker     }
371*789431f2SAndroid Build Coastguard Worker }
372*789431f2SAndroid Build Coastguard Worker 
373*789431f2SAndroid Build Coastguard Worker #define BPI 4 /* Number of blocks in buffer per ECB call */
374*789431f2SAndroid Build Coastguard Worker 
375*789431f2SAndroid Build Coastguard Worker /*-------------------*/
376*789431f2SAndroid Build Coastguard Worker #elif USE_REFERENCE_AES
377*789431f2SAndroid Build Coastguard Worker /*-------------------*/
378*789431f2SAndroid Build Coastguard Worker 
379*789431f2SAndroid Build Coastguard Worker #include "rijndael-alg-fst.h" /* Barreto's Public-Domain Code */
380*789431f2SAndroid Build Coastguard Worker #if (OCB_KEY_LEN == 0)
381*789431f2SAndroid Build Coastguard Worker typedef struct {
382*789431f2SAndroid Build Coastguard Worker     uint32_t rd_key[60];
383*789431f2SAndroid Build Coastguard Worker     int rounds;
384*789431f2SAndroid Build Coastguard Worker } AES_KEY;
385*789431f2SAndroid Build Coastguard Worker #define ROUNDS(ctx) ((ctx)->rounds)
386*789431f2SAndroid Build Coastguard Worker #define AES_set_encrypt_key(x, y, z)                                                               \
387*789431f2SAndroid Build Coastguard Worker     do {                                                                                           \
388*789431f2SAndroid Build Coastguard Worker         rijndaelKeySetupEnc((z)->rd_key, x, y);                                                    \
389*789431f2SAndroid Build Coastguard Worker         (z)->rounds = y / 32 + 6;                                                                  \
390*789431f2SAndroid Build Coastguard Worker     } while (0)
391*789431f2SAndroid Build Coastguard Worker #define AES_set_decrypt_key(x, y, z)                                                               \
392*789431f2SAndroid Build Coastguard Worker     do {                                                                                           \
393*789431f2SAndroid Build Coastguard Worker         rijndaelKeySetupDec((z)->rd_key, x, y);                                                    \
394*789431f2SAndroid Build Coastguard Worker         (z)->rounds = y / 32 + 6;                                                                  \
395*789431f2SAndroid Build Coastguard Worker     } while (0)
396*789431f2SAndroid Build Coastguard Worker #else
397*789431f2SAndroid Build Coastguard Worker typedef struct { uint32_t rd_key[OCB_KEY_LEN + 28]; } AES_KEY;
398*789431f2SAndroid Build Coastguard Worker #define ROUNDS(ctx) (6 + OCB_KEY_LEN / 4)
399*789431f2SAndroid Build Coastguard Worker #define AES_set_encrypt_key(x, y, z) rijndaelKeySetupEnc((z)->rd_key, x, y)
400*789431f2SAndroid Build Coastguard Worker #define AES_set_decrypt_key(x, y, z) rijndaelKeySetupDec((z)->rd_key, x, y)
401*789431f2SAndroid Build Coastguard Worker #endif
402*789431f2SAndroid Build Coastguard Worker #define AES_encrypt(x, y, z) rijndaelEncrypt((z)->rd_key, ROUNDS(z), x, y)
403*789431f2SAndroid Build Coastguard Worker #define AES_decrypt(x, y, z) rijndaelDecrypt((z)->rd_key, ROUNDS(z), x, y)
404*789431f2SAndroid Build Coastguard Worker 
AES_ecb_encrypt_blks(block * blks,unsigned nblks,AES_KEY * key)405*789431f2SAndroid Build Coastguard Worker static void AES_ecb_encrypt_blks(block* blks, unsigned nblks, AES_KEY* key) {
406*789431f2SAndroid Build Coastguard Worker     while (nblks) {
407*789431f2SAndroid Build Coastguard Worker         --nblks;
408*789431f2SAndroid Build Coastguard Worker         AES_encrypt((unsigned char*)(blks + nblks), (unsigned char*)(blks + nblks), key);
409*789431f2SAndroid Build Coastguard Worker     }
410*789431f2SAndroid Build Coastguard Worker }
411*789431f2SAndroid Build Coastguard Worker 
AES_ecb_decrypt_blks(block * blks,unsigned nblks,AES_KEY * key)412*789431f2SAndroid Build Coastguard Worker void AES_ecb_decrypt_blks(block* blks, unsigned nblks, AES_KEY* key) {
413*789431f2SAndroid Build Coastguard Worker     while (nblks) {
414*789431f2SAndroid Build Coastguard Worker         --nblks;
415*789431f2SAndroid Build Coastguard Worker         AES_decrypt((unsigned char*)(blks + nblks), (unsigned char*)(blks + nblks), key);
416*789431f2SAndroid Build Coastguard Worker     }
417*789431f2SAndroid Build Coastguard Worker }
418*789431f2SAndroid Build Coastguard Worker 
419*789431f2SAndroid Build Coastguard Worker #define BPI 4 /* Number of blocks in buffer per ECB call */
420*789431f2SAndroid Build Coastguard Worker 
421*789431f2SAndroid Build Coastguard Worker /*----------*/
422*789431f2SAndroid Build Coastguard Worker #elif USE_AES_NI
423*789431f2SAndroid Build Coastguard Worker /*----------*/
424*789431f2SAndroid Build Coastguard Worker 
425*789431f2SAndroid Build Coastguard Worker #include <wmmintrin.h>
426*789431f2SAndroid Build Coastguard Worker 
427*789431f2SAndroid Build Coastguard Worker #if (OCB_KEY_LEN == 0)
428*789431f2SAndroid Build Coastguard Worker typedef struct {
429*789431f2SAndroid Build Coastguard Worker     __m128i rd_key[15];
430*789431f2SAndroid Build Coastguard Worker     int rounds;
431*789431f2SAndroid Build Coastguard Worker } AES_KEY;
432*789431f2SAndroid Build Coastguard Worker #define ROUNDS(ctx) ((ctx)->rounds)
433*789431f2SAndroid Build Coastguard Worker #else
434*789431f2SAndroid Build Coastguard Worker typedef struct { __m128i rd_key[7 + OCB_KEY_LEN / 4]; } AES_KEY;
435*789431f2SAndroid Build Coastguard Worker #define ROUNDS(ctx) (6 + OCB_KEY_LEN / 4)
436*789431f2SAndroid Build Coastguard Worker #endif
437*789431f2SAndroid Build Coastguard Worker 
438*789431f2SAndroid Build Coastguard Worker #define EXPAND_ASSIST(v1, v2, v3, v4, shuff_const, aes_const)                                      \
439*789431f2SAndroid Build Coastguard Worker     v2 = _mm_aeskeygenassist_si128(v4, aes_const);                                                 \
440*789431f2SAndroid Build Coastguard Worker     v3 = _mm_castps_si128(_mm_shuffle_ps(_mm_castsi128_ps(v3), _mm_castsi128_ps(v1), 16));         \
441*789431f2SAndroid Build Coastguard Worker     v1 = _mm_xor_si128(v1, v3);                                                                    \
442*789431f2SAndroid Build Coastguard Worker     v3 = _mm_castps_si128(_mm_shuffle_ps(_mm_castsi128_ps(v3), _mm_castsi128_ps(v1), 140));        \
443*789431f2SAndroid Build Coastguard Worker     v1 = _mm_xor_si128(v1, v3);                                                                    \
444*789431f2SAndroid Build Coastguard Worker     v2 = _mm_shuffle_epi32(v2, shuff_const);                                                       \
445*789431f2SAndroid Build Coastguard Worker     v1 = _mm_xor_si128(v1, v2)
446*789431f2SAndroid Build Coastguard Worker 
447*789431f2SAndroid Build Coastguard Worker #define EXPAND192_STEP(idx, aes_const)                                                             \
448*789431f2SAndroid Build Coastguard Worker     EXPAND_ASSIST(x0, x1, x2, x3, 85, aes_const);                                                  \
449*789431f2SAndroid Build Coastguard Worker     x3 = _mm_xor_si128(x3, _mm_slli_si128(x3, 4));                                                 \
450*789431f2SAndroid Build Coastguard Worker     x3 = _mm_xor_si128(x3, _mm_shuffle_epi32(x0, 255));                                            \
451*789431f2SAndroid Build Coastguard Worker     kp[idx] = _mm_castps_si128(_mm_shuffle_ps(_mm_castsi128_ps(tmp), _mm_castsi128_ps(x0), 68));   \
452*789431f2SAndroid Build Coastguard Worker     kp[idx + 1] =                                                                                  \
453*789431f2SAndroid Build Coastguard Worker         _mm_castps_si128(_mm_shuffle_ps(_mm_castsi128_ps(x0), _mm_castsi128_ps(x3), 78));          \
454*789431f2SAndroid Build Coastguard Worker     EXPAND_ASSIST(x0, x1, x2, x3, 85, (aes_const * 2));                                            \
455*789431f2SAndroid Build Coastguard Worker     x3 = _mm_xor_si128(x3, _mm_slli_si128(x3, 4));                                                 \
456*789431f2SAndroid Build Coastguard Worker     x3 = _mm_xor_si128(x3, _mm_shuffle_epi32(x0, 255));                                            \
457*789431f2SAndroid Build Coastguard Worker     kp[idx + 2] = x0;                                                                              \
458*789431f2SAndroid Build Coastguard Worker     tmp = x3
459*789431f2SAndroid Build Coastguard Worker 
AES_128_Key_Expansion(const unsigned char * userkey,void * key)460*789431f2SAndroid Build Coastguard Worker static void AES_128_Key_Expansion(const unsigned char* userkey, void* key) {
461*789431f2SAndroid Build Coastguard Worker     __m128i x0, x1, x2;
462*789431f2SAndroid Build Coastguard Worker     __m128i* kp = (__m128i*)key;
463*789431f2SAndroid Build Coastguard Worker     kp[0] = x0 = _mm_loadu_si128((__m128i*)userkey);
464*789431f2SAndroid Build Coastguard Worker     x2 = _mm_setzero_si128();
465*789431f2SAndroid Build Coastguard Worker     EXPAND_ASSIST(x0, x1, x2, x0, 255, 1);
466*789431f2SAndroid Build Coastguard Worker     kp[1] = x0;
467*789431f2SAndroid Build Coastguard Worker     EXPAND_ASSIST(x0, x1, x2, x0, 255, 2);
468*789431f2SAndroid Build Coastguard Worker     kp[2] = x0;
469*789431f2SAndroid Build Coastguard Worker     EXPAND_ASSIST(x0, x1, x2, x0, 255, 4);
470*789431f2SAndroid Build Coastguard Worker     kp[3] = x0;
471*789431f2SAndroid Build Coastguard Worker     EXPAND_ASSIST(x0, x1, x2, x0, 255, 8);
472*789431f2SAndroid Build Coastguard Worker     kp[4] = x0;
473*789431f2SAndroid Build Coastguard Worker     EXPAND_ASSIST(x0, x1, x2, x0, 255, 16);
474*789431f2SAndroid Build Coastguard Worker     kp[5] = x0;
475*789431f2SAndroid Build Coastguard Worker     EXPAND_ASSIST(x0, x1, x2, x0, 255, 32);
476*789431f2SAndroid Build Coastguard Worker     kp[6] = x0;
477*789431f2SAndroid Build Coastguard Worker     EXPAND_ASSIST(x0, x1, x2, x0, 255, 64);
478*789431f2SAndroid Build Coastguard Worker     kp[7] = x0;
479*789431f2SAndroid Build Coastguard Worker     EXPAND_ASSIST(x0, x1, x2, x0, 255, 128);
480*789431f2SAndroid Build Coastguard Worker     kp[8] = x0;
481*789431f2SAndroid Build Coastguard Worker     EXPAND_ASSIST(x0, x1, x2, x0, 255, 27);
482*789431f2SAndroid Build Coastguard Worker     kp[9] = x0;
483*789431f2SAndroid Build Coastguard Worker     EXPAND_ASSIST(x0, x1, x2, x0, 255, 54);
484*789431f2SAndroid Build Coastguard Worker     kp[10] = x0;
485*789431f2SAndroid Build Coastguard Worker }
486*789431f2SAndroid Build Coastguard Worker 
AES_192_Key_Expansion(const unsigned char * userkey,void * key)487*789431f2SAndroid Build Coastguard Worker static void AES_192_Key_Expansion(const unsigned char* userkey, void* key) {
488*789431f2SAndroid Build Coastguard Worker     __m128i x0, x1, x2, x3, tmp, *kp = (__m128i*)key;
489*789431f2SAndroid Build Coastguard Worker     kp[0] = x0 = _mm_loadu_si128((__m128i*)userkey);
490*789431f2SAndroid Build Coastguard Worker     tmp = x3 = _mm_loadu_si128((__m128i*)(userkey + 16));
491*789431f2SAndroid Build Coastguard Worker     x2 = _mm_setzero_si128();
492*789431f2SAndroid Build Coastguard Worker     EXPAND192_STEP(1, 1);
493*789431f2SAndroid Build Coastguard Worker     EXPAND192_STEP(4, 4);
494*789431f2SAndroid Build Coastguard Worker     EXPAND192_STEP(7, 16);
495*789431f2SAndroid Build Coastguard Worker     EXPAND192_STEP(10, 64);
496*789431f2SAndroid Build Coastguard Worker }
497*789431f2SAndroid Build Coastguard Worker 
AES_256_Key_Expansion(const unsigned char * userkey,void * key)498*789431f2SAndroid Build Coastguard Worker static void AES_256_Key_Expansion(const unsigned char* userkey, void* key) {
499*789431f2SAndroid Build Coastguard Worker     __m128i x0, x1, x2, x3, *kp = (__m128i*)key;
500*789431f2SAndroid Build Coastguard Worker     kp[0] = x0 = _mm_loadu_si128((__m128i*)userkey);
501*789431f2SAndroid Build Coastguard Worker     kp[1] = x3 = _mm_loadu_si128((__m128i*)(userkey + 16));
502*789431f2SAndroid Build Coastguard Worker     x2 = _mm_setzero_si128();
503*789431f2SAndroid Build Coastguard Worker     EXPAND_ASSIST(x0, x1, x2, x3, 255, 1);
504*789431f2SAndroid Build Coastguard Worker     kp[2] = x0;
505*789431f2SAndroid Build Coastguard Worker     EXPAND_ASSIST(x3, x1, x2, x0, 170, 1);
506*789431f2SAndroid Build Coastguard Worker     kp[3] = x3;
507*789431f2SAndroid Build Coastguard Worker     EXPAND_ASSIST(x0, x1, x2, x3, 255, 2);
508*789431f2SAndroid Build Coastguard Worker     kp[4] = x0;
509*789431f2SAndroid Build Coastguard Worker     EXPAND_ASSIST(x3, x1, x2, x0, 170, 2);
510*789431f2SAndroid Build Coastguard Worker     kp[5] = x3;
511*789431f2SAndroid Build Coastguard Worker     EXPAND_ASSIST(x0, x1, x2, x3, 255, 4);
512*789431f2SAndroid Build Coastguard Worker     kp[6] = x0;
513*789431f2SAndroid Build Coastguard Worker     EXPAND_ASSIST(x3, x1, x2, x0, 170, 4);
514*789431f2SAndroid Build Coastguard Worker     kp[7] = x3;
515*789431f2SAndroid Build Coastguard Worker     EXPAND_ASSIST(x0, x1, x2, x3, 255, 8);
516*789431f2SAndroid Build Coastguard Worker     kp[8] = x0;
517*789431f2SAndroid Build Coastguard Worker     EXPAND_ASSIST(x3, x1, x2, x0, 170, 8);
518*789431f2SAndroid Build Coastguard Worker     kp[9] = x3;
519*789431f2SAndroid Build Coastguard Worker     EXPAND_ASSIST(x0, x1, x2, x3, 255, 16);
520*789431f2SAndroid Build Coastguard Worker     kp[10] = x0;
521*789431f2SAndroid Build Coastguard Worker     EXPAND_ASSIST(x3, x1, x2, x0, 170, 16);
522*789431f2SAndroid Build Coastguard Worker     kp[11] = x3;
523*789431f2SAndroid Build Coastguard Worker     EXPAND_ASSIST(x0, x1, x2, x3, 255, 32);
524*789431f2SAndroid Build Coastguard Worker     kp[12] = x0;
525*789431f2SAndroid Build Coastguard Worker     EXPAND_ASSIST(x3, x1, x2, x0, 170, 32);
526*789431f2SAndroid Build Coastguard Worker     kp[13] = x3;
527*789431f2SAndroid Build Coastguard Worker     EXPAND_ASSIST(x0, x1, x2, x3, 255, 64);
528*789431f2SAndroid Build Coastguard Worker     kp[14] = x0;
529*789431f2SAndroid Build Coastguard Worker }
530*789431f2SAndroid Build Coastguard Worker 
AES_set_encrypt_key(const unsigned char * userKey,const int bits,AES_KEY * key)531*789431f2SAndroid Build Coastguard Worker static int AES_set_encrypt_key(const unsigned char* userKey, const int bits, AES_KEY* key) {
532*789431f2SAndroid Build Coastguard Worker     if (bits == 128) {
533*789431f2SAndroid Build Coastguard Worker         AES_128_Key_Expansion(userKey, key);
534*789431f2SAndroid Build Coastguard Worker     } else if (bits == 192) {
535*789431f2SAndroid Build Coastguard Worker         AES_192_Key_Expansion(userKey, key);
536*789431f2SAndroid Build Coastguard Worker     } else if (bits == 256) {
537*789431f2SAndroid Build Coastguard Worker         AES_256_Key_Expansion(userKey, key);
538*789431f2SAndroid Build Coastguard Worker     }
539*789431f2SAndroid Build Coastguard Worker #if (OCB_KEY_LEN == 0)
540*789431f2SAndroid Build Coastguard Worker     key->rounds = 6 + bits / 32;
541*789431f2SAndroid Build Coastguard Worker #endif
542*789431f2SAndroid Build Coastguard Worker     return 0;
543*789431f2SAndroid Build Coastguard Worker }
544*789431f2SAndroid Build Coastguard Worker 
AES_set_decrypt_key_fast(AES_KEY * dkey,const AES_KEY * ekey)545*789431f2SAndroid Build Coastguard Worker static void AES_set_decrypt_key_fast(AES_KEY* dkey, const AES_KEY* ekey) {
546*789431f2SAndroid Build Coastguard Worker     int j = 0;
547*789431f2SAndroid Build Coastguard Worker     int i = ROUNDS(ekey);
548*789431f2SAndroid Build Coastguard Worker #if (OCB_KEY_LEN == 0)
549*789431f2SAndroid Build Coastguard Worker     dkey->rounds = i;
550*789431f2SAndroid Build Coastguard Worker #endif
551*789431f2SAndroid Build Coastguard Worker     dkey->rd_key[i--] = ekey->rd_key[j++];
552*789431f2SAndroid Build Coastguard Worker     while (i)
553*789431f2SAndroid Build Coastguard Worker         dkey->rd_key[i--] = _mm_aesimc_si128(ekey->rd_key[j++]);
554*789431f2SAndroid Build Coastguard Worker     dkey->rd_key[i] = ekey->rd_key[j];
555*789431f2SAndroid Build Coastguard Worker }
556*789431f2SAndroid Build Coastguard Worker 
AES_set_decrypt_key(const unsigned char * userKey,const int bits,AES_KEY * key)557*789431f2SAndroid Build Coastguard Worker static int AES_set_decrypt_key(const unsigned char* userKey, const int bits, AES_KEY* key) {
558*789431f2SAndroid Build Coastguard Worker     AES_KEY temp_key;
559*789431f2SAndroid Build Coastguard Worker     AES_set_encrypt_key(userKey, bits, &temp_key);
560*789431f2SAndroid Build Coastguard Worker     AES_set_decrypt_key_fast(key, &temp_key);
561*789431f2SAndroid Build Coastguard Worker     return 0;
562*789431f2SAndroid Build Coastguard Worker }
563*789431f2SAndroid Build Coastguard Worker 
AES_encrypt(const unsigned char * in,unsigned char * out,const AES_KEY * key)564*789431f2SAndroid Build Coastguard Worker static inline void AES_encrypt(const unsigned char* in, unsigned char* out, const AES_KEY* key) {
565*789431f2SAndroid Build Coastguard Worker     int j, rnds = ROUNDS(key);
566*789431f2SAndroid Build Coastguard Worker     const __m128i* sched = ((__m128i*)(key->rd_key));
567*789431f2SAndroid Build Coastguard Worker     __m128i tmp = _mm_load_si128((__m128i*)in);
568*789431f2SAndroid Build Coastguard Worker     tmp = _mm_xor_si128(tmp, sched[0]);
569*789431f2SAndroid Build Coastguard Worker     for (j = 1; j < rnds; j++)
570*789431f2SAndroid Build Coastguard Worker         tmp = _mm_aesenc_si128(tmp, sched[j]);
571*789431f2SAndroid Build Coastguard Worker     tmp = _mm_aesenclast_si128(tmp, sched[j]);
572*789431f2SAndroid Build Coastguard Worker     _mm_store_si128((__m128i*)out, tmp);
573*789431f2SAndroid Build Coastguard Worker }
574*789431f2SAndroid Build Coastguard Worker 
AES_decrypt(const unsigned char * in,unsigned char * out,const AES_KEY * key)575*789431f2SAndroid Build Coastguard Worker static inline void AES_decrypt(const unsigned char* in, unsigned char* out, const AES_KEY* key) {
576*789431f2SAndroid Build Coastguard Worker     int j, rnds = ROUNDS(key);
577*789431f2SAndroid Build Coastguard Worker     const __m128i* sched = ((__m128i*)(key->rd_key));
578*789431f2SAndroid Build Coastguard Worker     __m128i tmp = _mm_load_si128((__m128i*)in);
579*789431f2SAndroid Build Coastguard Worker     tmp = _mm_xor_si128(tmp, sched[0]);
580*789431f2SAndroid Build Coastguard Worker     for (j = 1; j < rnds; j++)
581*789431f2SAndroid Build Coastguard Worker         tmp = _mm_aesdec_si128(tmp, sched[j]);
582*789431f2SAndroid Build Coastguard Worker     tmp = _mm_aesdeclast_si128(tmp, sched[j]);
583*789431f2SAndroid Build Coastguard Worker     _mm_store_si128((__m128i*)out, tmp);
584*789431f2SAndroid Build Coastguard Worker }
585*789431f2SAndroid Build Coastguard Worker 
AES_ecb_encrypt_blks(block * blks,unsigned nblks,AES_KEY * key)586*789431f2SAndroid Build Coastguard Worker static inline void AES_ecb_encrypt_blks(block* blks, unsigned nblks, AES_KEY* key) {
587*789431f2SAndroid Build Coastguard Worker     unsigned i, j, rnds = ROUNDS(key);
588*789431f2SAndroid Build Coastguard Worker     const __m128i* sched = ((__m128i*)(key->rd_key));
589*789431f2SAndroid Build Coastguard Worker     for (i = 0; i < nblks; ++i)
590*789431f2SAndroid Build Coastguard Worker         blks[i] = _mm_xor_si128(blks[i], sched[0]);
591*789431f2SAndroid Build Coastguard Worker     for (j = 1; j < rnds; ++j)
592*789431f2SAndroid Build Coastguard Worker         for (i = 0; i < nblks; ++i)
593*789431f2SAndroid Build Coastguard Worker             blks[i] = _mm_aesenc_si128(blks[i], sched[j]);
594*789431f2SAndroid Build Coastguard Worker     for (i = 0; i < nblks; ++i)
595*789431f2SAndroid Build Coastguard Worker         blks[i] = _mm_aesenclast_si128(blks[i], sched[j]);
596*789431f2SAndroid Build Coastguard Worker }
597*789431f2SAndroid Build Coastguard Worker 
AES_ecb_decrypt_blks(block * blks,unsigned nblks,AES_KEY * key)598*789431f2SAndroid Build Coastguard Worker static inline void AES_ecb_decrypt_blks(block* blks, unsigned nblks, AES_KEY* key) {
599*789431f2SAndroid Build Coastguard Worker     unsigned i, j, rnds = ROUNDS(key);
600*789431f2SAndroid Build Coastguard Worker     const __m128i* sched = ((__m128i*)(key->rd_key));
601*789431f2SAndroid Build Coastguard Worker     for (i = 0; i < nblks; ++i)
602*789431f2SAndroid Build Coastguard Worker         blks[i] = _mm_xor_si128(blks[i], sched[0]);
603*789431f2SAndroid Build Coastguard Worker     for (j = 1; j < rnds; ++j)
604*789431f2SAndroid Build Coastguard Worker         for (i = 0; i < nblks; ++i)
605*789431f2SAndroid Build Coastguard Worker             blks[i] = _mm_aesdec_si128(blks[i], sched[j]);
606*789431f2SAndroid Build Coastguard Worker     for (i = 0; i < nblks; ++i)
607*789431f2SAndroid Build Coastguard Worker         blks[i] = _mm_aesdeclast_si128(blks[i], sched[j]);
608*789431f2SAndroid Build Coastguard Worker }
609*789431f2SAndroid Build Coastguard Worker 
610*789431f2SAndroid Build Coastguard Worker #define BPI 8 /* Number of blocks in buffer per ECB call   */
611*789431f2SAndroid Build Coastguard Worker /* Set to 4 for Westmere, 8 for Sandy Bridge */
612*789431f2SAndroid Build Coastguard Worker 
613*789431f2SAndroid Build Coastguard Worker #endif
614*789431f2SAndroid Build Coastguard Worker 
615*789431f2SAndroid Build Coastguard Worker /* ----------------------------------------------------------------------- */
616*789431f2SAndroid Build Coastguard Worker /* Define OCB context structure.                                           */
617*789431f2SAndroid Build Coastguard Worker /* ----------------------------------------------------------------------- */
618*789431f2SAndroid Build Coastguard Worker 
619*789431f2SAndroid Build Coastguard Worker /*------------------------------------------------------------------------
620*789431f2SAndroid Build Coastguard Worker / Each item in the OCB context is stored either "memory correct" or
621*789431f2SAndroid Build Coastguard Worker / "register correct". On big-endian machines, this is identical. On
622*789431f2SAndroid Build Coastguard Worker / little-endian machines, one must choose whether the byte-string
623*789431f2SAndroid Build Coastguard Worker / is in the correct order when it resides in memory or in registers.
624*789431f2SAndroid Build Coastguard Worker / It must be register correct whenever it is to be manipulated
625*789431f2SAndroid Build Coastguard Worker / arithmetically, but must be memory correct whenever it interacts
626*789431f2SAndroid Build Coastguard Worker / with the plaintext or ciphertext.
627*789431f2SAndroid Build Coastguard Worker /------------------------------------------------------------------------- */
628*789431f2SAndroid Build Coastguard Worker 
629*789431f2SAndroid Build Coastguard Worker struct _ae_ctx {
630*789431f2SAndroid Build Coastguard Worker     block offset;        /* Memory correct               */
631*789431f2SAndroid Build Coastguard Worker     block checksum;      /* Memory correct               */
632*789431f2SAndroid Build Coastguard Worker     block Lstar;         /* Memory correct               */
633*789431f2SAndroid Build Coastguard Worker     block Ldollar;       /* Memory correct               */
634*789431f2SAndroid Build Coastguard Worker     block L[L_TABLE_SZ]; /* Memory correct               */
635*789431f2SAndroid Build Coastguard Worker     block ad_checksum;   /* Memory correct               */
636*789431f2SAndroid Build Coastguard Worker     block ad_offset;     /* Memory correct               */
637*789431f2SAndroid Build Coastguard Worker     block cached_Top;    /* Memory correct               */
638*789431f2SAndroid Build Coastguard Worker     uint64_t KtopStr[3]; /* Register correct, each item  */
639*789431f2SAndroid Build Coastguard Worker     uint32_t ad_blocks_processed;
640*789431f2SAndroid Build Coastguard Worker     uint32_t blocks_processed;
641*789431f2SAndroid Build Coastguard Worker     AES_KEY decrypt_key;
642*789431f2SAndroid Build Coastguard Worker     AES_KEY encrypt_key;
643*789431f2SAndroid Build Coastguard Worker #if (OCB_TAG_LEN == 0)
644*789431f2SAndroid Build Coastguard Worker     unsigned tag_len;
645*789431f2SAndroid Build Coastguard Worker #endif
646*789431f2SAndroid Build Coastguard Worker };
647*789431f2SAndroid Build Coastguard Worker 
648*789431f2SAndroid Build Coastguard Worker /* ----------------------------------------------------------------------- */
649*789431f2SAndroid Build Coastguard Worker /* L table lookup (or on-the-fly generation)                               */
650*789431f2SAndroid Build Coastguard Worker /* ----------------------------------------------------------------------- */
651*789431f2SAndroid Build Coastguard Worker 
652*789431f2SAndroid Build Coastguard Worker #if L_TABLE_SZ_IS_ENOUGH
653*789431f2SAndroid Build Coastguard Worker #define getL(_ctx, _tz) ((_ctx)->L[_tz])
654*789431f2SAndroid Build Coastguard Worker #else
getL(const ae_ctx * ctx,unsigned tz)655*789431f2SAndroid Build Coastguard Worker static block getL(const ae_ctx* ctx, unsigned tz) {
656*789431f2SAndroid Build Coastguard Worker     if (tz < L_TABLE_SZ)
657*789431f2SAndroid Build Coastguard Worker         return ctx->L[tz];
658*789431f2SAndroid Build Coastguard Worker     else {
659*789431f2SAndroid Build Coastguard Worker         unsigned i;
660*789431f2SAndroid Build Coastguard Worker         /* Bring L[MAX] into registers, make it register correct */
661*789431f2SAndroid Build Coastguard Worker         block rval = swap_if_le(ctx->L[L_TABLE_SZ - 1]);
662*789431f2SAndroid Build Coastguard Worker         rval = double_block(rval);
663*789431f2SAndroid Build Coastguard Worker         for (i = L_TABLE_SZ; i < tz; i++)
664*789431f2SAndroid Build Coastguard Worker             rval = double_block(rval);
665*789431f2SAndroid Build Coastguard Worker         return swap_if_le(rval); /* To memory correct */
666*789431f2SAndroid Build Coastguard Worker     }
667*789431f2SAndroid Build Coastguard Worker }
668*789431f2SAndroid Build Coastguard Worker #endif
669*789431f2SAndroid Build Coastguard Worker 
670*789431f2SAndroid Build Coastguard Worker /* ----------------------------------------------------------------------- */
671*789431f2SAndroid Build Coastguard Worker /* Public functions                                                        */
672*789431f2SAndroid Build Coastguard Worker /* ----------------------------------------------------------------------- */
673*789431f2SAndroid Build Coastguard Worker 
674*789431f2SAndroid Build Coastguard Worker /* 32-bit SSE2 and Altivec systems need to be forced to allocate memory
675*789431f2SAndroid Build Coastguard Worker    on 16-byte alignments. (I believe all major 64-bit systems do already.) */
676*789431f2SAndroid Build Coastguard Worker 
ae_allocate(void * misc)677*789431f2SAndroid Build Coastguard Worker ae_ctx* ae_allocate(void* misc) {
678*789431f2SAndroid Build Coastguard Worker     void* p;
679*789431f2SAndroid Build Coastguard Worker     (void)misc; /* misc unused in this implementation */
680*789431f2SAndroid Build Coastguard Worker #if (__SSE2__ && !_M_X64 && !_M_AMD64 && !__amd64__)
681*789431f2SAndroid Build Coastguard Worker     p = _mm_malloc(sizeof(ae_ctx), 16);
682*789431f2SAndroid Build Coastguard Worker #elif ((__ALTIVEC__ && !__PPC64__) || __ARM_NEON__)
683*789431f2SAndroid Build Coastguard Worker     if (posix_memalign(&p, 16, sizeof(ae_ctx)) != 0) p = NULL;
684*789431f2SAndroid Build Coastguard Worker #else
685*789431f2SAndroid Build Coastguard Worker     p = malloc(sizeof(ae_ctx));
686*789431f2SAndroid Build Coastguard Worker #endif
687*789431f2SAndroid Build Coastguard Worker     return (ae_ctx*)p;
688*789431f2SAndroid Build Coastguard Worker }
689*789431f2SAndroid Build Coastguard Worker 
ae_free(ae_ctx * ctx)690*789431f2SAndroid Build Coastguard Worker void ae_free(ae_ctx* ctx) {
691*789431f2SAndroid Build Coastguard Worker #if (__SSE2__ && !_M_X64 && !_M_AMD64 && !__amd64__)
692*789431f2SAndroid Build Coastguard Worker     _mm_free(ctx);
693*789431f2SAndroid Build Coastguard Worker #else
694*789431f2SAndroid Build Coastguard Worker     free(ctx);
695*789431f2SAndroid Build Coastguard Worker #endif
696*789431f2SAndroid Build Coastguard Worker }
697*789431f2SAndroid Build Coastguard Worker 
698*789431f2SAndroid Build Coastguard Worker /* ----------------------------------------------------------------------- */
699*789431f2SAndroid Build Coastguard Worker 
ae_clear(ae_ctx * ctx)700*789431f2SAndroid Build Coastguard Worker int ae_clear(ae_ctx* ctx) /* Zero ae_ctx and undo initialization          */
701*789431f2SAndroid Build Coastguard Worker {
702*789431f2SAndroid Build Coastguard Worker     memset(ctx, 0, sizeof(ae_ctx));
703*789431f2SAndroid Build Coastguard Worker     return AE_SUCCESS;
704*789431f2SAndroid Build Coastguard Worker }
705*789431f2SAndroid Build Coastguard Worker 
ae_ctx_sizeof(void)706*789431f2SAndroid Build Coastguard Worker int ae_ctx_sizeof(void) {
707*789431f2SAndroid Build Coastguard Worker     return (int)sizeof(ae_ctx);
708*789431f2SAndroid Build Coastguard Worker }
709*789431f2SAndroid Build Coastguard Worker 
710*789431f2SAndroid Build Coastguard Worker /* ----------------------------------------------------------------------- */
711*789431f2SAndroid Build Coastguard Worker 
ae_init(ae_ctx * ctx,const void * key,int key_len,int nonce_len,int tag_len)712*789431f2SAndroid Build Coastguard Worker int ae_init(ae_ctx* ctx, const void* key, int key_len, int nonce_len, int tag_len) {
713*789431f2SAndroid Build Coastguard Worker     unsigned i;
714*789431f2SAndroid Build Coastguard Worker     block tmp_blk;
715*789431f2SAndroid Build Coastguard Worker 
716*789431f2SAndroid Build Coastguard Worker     if (nonce_len != 12)
717*789431f2SAndroid Build Coastguard Worker         return AE_NOT_SUPPORTED;
718*789431f2SAndroid Build Coastguard Worker 
719*789431f2SAndroid Build Coastguard Worker /* Initialize encryption & decryption keys */
720*789431f2SAndroid Build Coastguard Worker #if (OCB_KEY_LEN > 0)
721*789431f2SAndroid Build Coastguard Worker     key_len = OCB_KEY_LEN;
722*789431f2SAndroid Build Coastguard Worker #endif
723*789431f2SAndroid Build Coastguard Worker     AES_set_encrypt_key((unsigned char*)key, key_len * 8, &ctx->encrypt_key);
724*789431f2SAndroid Build Coastguard Worker #if USE_AES_NI
725*789431f2SAndroid Build Coastguard Worker     AES_set_decrypt_key_fast(&ctx->decrypt_key, &ctx->encrypt_key);
726*789431f2SAndroid Build Coastguard Worker #else
727*789431f2SAndroid Build Coastguard Worker     AES_set_decrypt_key((unsigned char*)key, (int)(key_len * 8), &ctx->decrypt_key);
728*789431f2SAndroid Build Coastguard Worker #endif
729*789431f2SAndroid Build Coastguard Worker 
730*789431f2SAndroid Build Coastguard Worker     /* Zero things that need zeroing */
731*789431f2SAndroid Build Coastguard Worker     ctx->cached_Top = ctx->ad_checksum = zero_block();
732*789431f2SAndroid Build Coastguard Worker     ctx->ad_blocks_processed = 0;
733*789431f2SAndroid Build Coastguard Worker 
734*789431f2SAndroid Build Coastguard Worker     /* Compute key-dependent values */
735*789431f2SAndroid Build Coastguard Worker     AES_encrypt((unsigned char*)&ctx->cached_Top, (unsigned char*)&ctx->Lstar, &ctx->encrypt_key);
736*789431f2SAndroid Build Coastguard Worker     tmp_blk = swap_if_le(ctx->Lstar);
737*789431f2SAndroid Build Coastguard Worker     tmp_blk = double_block(tmp_blk);
738*789431f2SAndroid Build Coastguard Worker     ctx->Ldollar = swap_if_le(tmp_blk);
739*789431f2SAndroid Build Coastguard Worker     tmp_blk = double_block(tmp_blk);
740*789431f2SAndroid Build Coastguard Worker     ctx->L[0] = swap_if_le(tmp_blk);
741*789431f2SAndroid Build Coastguard Worker     for (i = 1; i < L_TABLE_SZ; i++) {
742*789431f2SAndroid Build Coastguard Worker         tmp_blk = double_block(tmp_blk);
743*789431f2SAndroid Build Coastguard Worker         ctx->L[i] = swap_if_le(tmp_blk);
744*789431f2SAndroid Build Coastguard Worker     }
745*789431f2SAndroid Build Coastguard Worker 
746*789431f2SAndroid Build Coastguard Worker #if (OCB_TAG_LEN == 0)
747*789431f2SAndroid Build Coastguard Worker     ctx->tag_len = tag_len;
748*789431f2SAndroid Build Coastguard Worker #else
749*789431f2SAndroid Build Coastguard Worker     (void)tag_len; /* Suppress var not used error */
750*789431f2SAndroid Build Coastguard Worker #endif
751*789431f2SAndroid Build Coastguard Worker 
752*789431f2SAndroid Build Coastguard Worker     return AE_SUCCESS;
753*789431f2SAndroid Build Coastguard Worker }
754*789431f2SAndroid Build Coastguard Worker 
755*789431f2SAndroid Build Coastguard Worker /* ----------------------------------------------------------------------- */
756*789431f2SAndroid Build Coastguard Worker 
gen_offset_from_nonce(ae_ctx * ctx,const void * nonce)757*789431f2SAndroid Build Coastguard Worker static block gen_offset_from_nonce(ae_ctx* ctx, const void* nonce) {
758*789431f2SAndroid Build Coastguard Worker     const union {
759*789431f2SAndroid Build Coastguard Worker         unsigned x;
760*789431f2SAndroid Build Coastguard Worker         unsigned char endian;
761*789431f2SAndroid Build Coastguard Worker     } little = {1};
762*789431f2SAndroid Build Coastguard Worker     union {
763*789431f2SAndroid Build Coastguard Worker         uint32_t u32[4];
764*789431f2SAndroid Build Coastguard Worker         uint8_t u8[16];
765*789431f2SAndroid Build Coastguard Worker         block bl;
766*789431f2SAndroid Build Coastguard Worker     } tmp;
767*789431f2SAndroid Build Coastguard Worker     unsigned idx;
768*789431f2SAndroid Build Coastguard Worker 
769*789431f2SAndroid Build Coastguard Worker /* Replace cached nonce Top if needed */
770*789431f2SAndroid Build Coastguard Worker #if (OCB_TAG_LEN > 0)
771*789431f2SAndroid Build Coastguard Worker     if (little.endian)
772*789431f2SAndroid Build Coastguard Worker         tmp.u32[0] = 0x01000000 + ((OCB_TAG_LEN * 8 % 128) << 1);
773*789431f2SAndroid Build Coastguard Worker     else
774*789431f2SAndroid Build Coastguard Worker         tmp.u32[0] = 0x00000001 + ((OCB_TAG_LEN * 8 % 128) << 25);
775*789431f2SAndroid Build Coastguard Worker #else
776*789431f2SAndroid Build Coastguard Worker     if (little.endian)
777*789431f2SAndroid Build Coastguard Worker         tmp.u32[0] = 0x01000000 + ((ctx->tag_len * 8 % 128) << 1);
778*789431f2SAndroid Build Coastguard Worker     else
779*789431f2SAndroid Build Coastguard Worker         tmp.u32[0] = 0x00000001 + ((ctx->tag_len * 8 % 128) << 25);
780*789431f2SAndroid Build Coastguard Worker #endif
781*789431f2SAndroid Build Coastguard Worker     tmp.u32[1] = ((uint32_t*)nonce)[0];
782*789431f2SAndroid Build Coastguard Worker     tmp.u32[2] = ((uint32_t*)nonce)[1];
783*789431f2SAndroid Build Coastguard Worker     tmp.u32[3] = ((uint32_t*)nonce)[2];
784*789431f2SAndroid Build Coastguard Worker     idx = (unsigned)(tmp.u8[15] & 0x3f);           /* Get low 6 bits of nonce  */
785*789431f2SAndroid Build Coastguard Worker     tmp.u8[15] = tmp.u8[15] & 0xc0;                /* Zero low 6 bits of nonce */
786*789431f2SAndroid Build Coastguard Worker     if (unequal_blocks(tmp.bl, ctx->cached_Top)) { /* Cached?       */
787*789431f2SAndroid Build Coastguard Worker         ctx->cached_Top = tmp.bl;                  /* Update cache, KtopStr    */
788*789431f2SAndroid Build Coastguard Worker         AES_encrypt(tmp.u8, (unsigned char*)&ctx->KtopStr, &ctx->encrypt_key);
789*789431f2SAndroid Build Coastguard Worker         if (little.endian) { /* Make Register Correct    */
790*789431f2SAndroid Build Coastguard Worker             ctx->KtopStr[0] = bswap64(ctx->KtopStr[0]);
791*789431f2SAndroid Build Coastguard Worker             ctx->KtopStr[1] = bswap64(ctx->KtopStr[1]);
792*789431f2SAndroid Build Coastguard Worker         }
793*789431f2SAndroid Build Coastguard Worker         ctx->KtopStr[2] = ctx->KtopStr[0] ^ (ctx->KtopStr[0] << 8) ^ (ctx->KtopStr[1] >> 56);
794*789431f2SAndroid Build Coastguard Worker     }
795*789431f2SAndroid Build Coastguard Worker     return gen_offset(ctx->KtopStr, idx);
796*789431f2SAndroid Build Coastguard Worker }
797*789431f2SAndroid Build Coastguard Worker 
process_ad(ae_ctx * ctx,const void * ad,int ad_len,int final)798*789431f2SAndroid Build Coastguard Worker static void process_ad(ae_ctx* ctx, const void* ad, int ad_len, int final) {
799*789431f2SAndroid Build Coastguard Worker     union {
800*789431f2SAndroid Build Coastguard Worker         uint32_t u32[4];
801*789431f2SAndroid Build Coastguard Worker         uint8_t u8[16];
802*789431f2SAndroid Build Coastguard Worker         block bl;
803*789431f2SAndroid Build Coastguard Worker     } tmp;
804*789431f2SAndroid Build Coastguard Worker     block ad_offset, ad_checksum;
805*789431f2SAndroid Build Coastguard Worker     const block* adp = (block*)ad;
806*789431f2SAndroid Build Coastguard Worker     unsigned i, k, tz, remaining;
807*789431f2SAndroid Build Coastguard Worker 
808*789431f2SAndroid Build Coastguard Worker     ad_offset = ctx->ad_offset;
809*789431f2SAndroid Build Coastguard Worker     ad_checksum = ctx->ad_checksum;
810*789431f2SAndroid Build Coastguard Worker     i = ad_len / (BPI * 16);
811*789431f2SAndroid Build Coastguard Worker     if (i) {
812*789431f2SAndroid Build Coastguard Worker         unsigned ad_block_num = ctx->ad_blocks_processed;
813*789431f2SAndroid Build Coastguard Worker         do {
814*789431f2SAndroid Build Coastguard Worker             block ta[BPI], oa[BPI];
815*789431f2SAndroid Build Coastguard Worker             ad_block_num += BPI;
816*789431f2SAndroid Build Coastguard Worker             tz = ntz(ad_block_num);
817*789431f2SAndroid Build Coastguard Worker             oa[0] = xor_block(ad_offset, ctx->L[0]);
818*789431f2SAndroid Build Coastguard Worker             ta[0] = xor_block(oa[0], adp[0]);
819*789431f2SAndroid Build Coastguard Worker             oa[1] = xor_block(oa[0], ctx->L[1]);
820*789431f2SAndroid Build Coastguard Worker             ta[1] = xor_block(oa[1], adp[1]);
821*789431f2SAndroid Build Coastguard Worker             oa[2] = xor_block(ad_offset, ctx->L[1]);
822*789431f2SAndroid Build Coastguard Worker             ta[2] = xor_block(oa[2], adp[2]);
823*789431f2SAndroid Build Coastguard Worker #if BPI == 4
824*789431f2SAndroid Build Coastguard Worker             ad_offset = xor_block(oa[2], getL(ctx, tz));
825*789431f2SAndroid Build Coastguard Worker             ta[3] = xor_block(ad_offset, adp[3]);
826*789431f2SAndroid Build Coastguard Worker #elif BPI == 8
827*789431f2SAndroid Build Coastguard Worker             oa[3] = xor_block(oa[2], ctx->L[2]);
828*789431f2SAndroid Build Coastguard Worker             ta[3] = xor_block(oa[3], adp[3]);
829*789431f2SAndroid Build Coastguard Worker             oa[4] = xor_block(oa[1], ctx->L[2]);
830*789431f2SAndroid Build Coastguard Worker             ta[4] = xor_block(oa[4], adp[4]);
831*789431f2SAndroid Build Coastguard Worker             oa[5] = xor_block(oa[0], ctx->L[2]);
832*789431f2SAndroid Build Coastguard Worker             ta[5] = xor_block(oa[5], adp[5]);
833*789431f2SAndroid Build Coastguard Worker             oa[6] = xor_block(ad_offset, ctx->L[2]);
834*789431f2SAndroid Build Coastguard Worker             ta[6] = xor_block(oa[6], adp[6]);
835*789431f2SAndroid Build Coastguard Worker             ad_offset = xor_block(oa[6], getL(ctx, tz));
836*789431f2SAndroid Build Coastguard Worker             ta[7] = xor_block(ad_offset, adp[7]);
837*789431f2SAndroid Build Coastguard Worker #endif
838*789431f2SAndroid Build Coastguard Worker             AES_ecb_encrypt_blks(ta, BPI, &ctx->encrypt_key);
839*789431f2SAndroid Build Coastguard Worker             ad_checksum = xor_block(ad_checksum, ta[0]);
840*789431f2SAndroid Build Coastguard Worker             ad_checksum = xor_block(ad_checksum, ta[1]);
841*789431f2SAndroid Build Coastguard Worker             ad_checksum = xor_block(ad_checksum, ta[2]);
842*789431f2SAndroid Build Coastguard Worker             ad_checksum = xor_block(ad_checksum, ta[3]);
843*789431f2SAndroid Build Coastguard Worker #if (BPI == 8)
844*789431f2SAndroid Build Coastguard Worker             ad_checksum = xor_block(ad_checksum, ta[4]);
845*789431f2SAndroid Build Coastguard Worker             ad_checksum = xor_block(ad_checksum, ta[5]);
846*789431f2SAndroid Build Coastguard Worker             ad_checksum = xor_block(ad_checksum, ta[6]);
847*789431f2SAndroid Build Coastguard Worker             ad_checksum = xor_block(ad_checksum, ta[7]);
848*789431f2SAndroid Build Coastguard Worker #endif
849*789431f2SAndroid Build Coastguard Worker             adp += BPI;
850*789431f2SAndroid Build Coastguard Worker         } while (--i);
851*789431f2SAndroid Build Coastguard Worker         ctx->ad_blocks_processed = ad_block_num;
852*789431f2SAndroid Build Coastguard Worker         ctx->ad_offset = ad_offset;
853*789431f2SAndroid Build Coastguard Worker         ctx->ad_checksum = ad_checksum;
854*789431f2SAndroid Build Coastguard Worker     }
855*789431f2SAndroid Build Coastguard Worker 
856*789431f2SAndroid Build Coastguard Worker     if (final) {
857*789431f2SAndroid Build Coastguard Worker         block ta[BPI];
858*789431f2SAndroid Build Coastguard Worker 
859*789431f2SAndroid Build Coastguard Worker         /* Process remaining associated data, compute its tag contribution */
860*789431f2SAndroid Build Coastguard Worker         remaining = ((unsigned)ad_len) % (BPI * 16);
861*789431f2SAndroid Build Coastguard Worker         if (remaining) {
862*789431f2SAndroid Build Coastguard Worker             k = 0;
863*789431f2SAndroid Build Coastguard Worker #if (BPI == 8)
864*789431f2SAndroid Build Coastguard Worker             if (remaining >= 64) {
865*789431f2SAndroid Build Coastguard Worker                 tmp.bl = xor_block(ad_offset, ctx->L[0]);
866*789431f2SAndroid Build Coastguard Worker                 ta[0] = xor_block(tmp.bl, adp[0]);
867*789431f2SAndroid Build Coastguard Worker                 tmp.bl = xor_block(tmp.bl, ctx->L[1]);
868*789431f2SAndroid Build Coastguard Worker                 ta[1] = xor_block(tmp.bl, adp[1]);
869*789431f2SAndroid Build Coastguard Worker                 ad_offset = xor_block(ad_offset, ctx->L[1]);
870*789431f2SAndroid Build Coastguard Worker                 ta[2] = xor_block(ad_offset, adp[2]);
871*789431f2SAndroid Build Coastguard Worker                 ad_offset = xor_block(ad_offset, ctx->L[2]);
872*789431f2SAndroid Build Coastguard Worker                 ta[3] = xor_block(ad_offset, adp[3]);
873*789431f2SAndroid Build Coastguard Worker                 remaining -= 64;
874*789431f2SAndroid Build Coastguard Worker                 k = 4;
875*789431f2SAndroid Build Coastguard Worker             }
876*789431f2SAndroid Build Coastguard Worker #endif
877*789431f2SAndroid Build Coastguard Worker             if (remaining >= 32) {
878*789431f2SAndroid Build Coastguard Worker                 ad_offset = xor_block(ad_offset, ctx->L[0]);
879*789431f2SAndroid Build Coastguard Worker                 ta[k] = xor_block(ad_offset, adp[k]);
880*789431f2SAndroid Build Coastguard Worker                 ad_offset = xor_block(ad_offset, getL(ctx, ntz(k + 2)));
881*789431f2SAndroid Build Coastguard Worker                 ta[k + 1] = xor_block(ad_offset, adp[k + 1]);
882*789431f2SAndroid Build Coastguard Worker                 remaining -= 32;
883*789431f2SAndroid Build Coastguard Worker                 k += 2;
884*789431f2SAndroid Build Coastguard Worker             }
885*789431f2SAndroid Build Coastguard Worker             if (remaining >= 16) {
886*789431f2SAndroid Build Coastguard Worker                 ad_offset = xor_block(ad_offset, ctx->L[0]);
887*789431f2SAndroid Build Coastguard Worker                 ta[k] = xor_block(ad_offset, adp[k]);
888*789431f2SAndroid Build Coastguard Worker                 remaining = remaining - 16;
889*789431f2SAndroid Build Coastguard Worker                 ++k;
890*789431f2SAndroid Build Coastguard Worker             }
891*789431f2SAndroid Build Coastguard Worker             if (remaining) {
892*789431f2SAndroid Build Coastguard Worker                 ad_offset = xor_block(ad_offset, ctx->Lstar);
893*789431f2SAndroid Build Coastguard Worker                 tmp.bl = zero_block();
894*789431f2SAndroid Build Coastguard Worker                 memcpy(tmp.u8, adp + k, remaining);
895*789431f2SAndroid Build Coastguard Worker                 tmp.u8[remaining] = (unsigned char)0x80u;
896*789431f2SAndroid Build Coastguard Worker                 ta[k] = xor_block(ad_offset, tmp.bl);
897*789431f2SAndroid Build Coastguard Worker                 ++k;
898*789431f2SAndroid Build Coastguard Worker             }
899*789431f2SAndroid Build Coastguard Worker             AES_ecb_encrypt_blks(ta, k, &ctx->encrypt_key);
900*789431f2SAndroid Build Coastguard Worker             switch (k) {
901*789431f2SAndroid Build Coastguard Worker #if (BPI == 8)
902*789431f2SAndroid Build Coastguard Worker             case 8:
903*789431f2SAndroid Build Coastguard Worker                 ad_checksum = xor_block(ad_checksum, ta[7]);
904*789431f2SAndroid Build Coastguard Worker                 __fallthrough;
905*789431f2SAndroid Build Coastguard Worker             case 7:
906*789431f2SAndroid Build Coastguard Worker                 ad_checksum = xor_block(ad_checksum, ta[6]);
907*789431f2SAndroid Build Coastguard Worker                 __fallthrough;
908*789431f2SAndroid Build Coastguard Worker             case 6:
909*789431f2SAndroid Build Coastguard Worker                 ad_checksum = xor_block(ad_checksum, ta[5]);
910*789431f2SAndroid Build Coastguard Worker                 __fallthrough;
911*789431f2SAndroid Build Coastguard Worker             case 5:
912*789431f2SAndroid Build Coastguard Worker                 ad_checksum = xor_block(ad_checksum, ta[4]);
913*789431f2SAndroid Build Coastguard Worker                 __fallthrough;
914*789431f2SAndroid Build Coastguard Worker #endif
915*789431f2SAndroid Build Coastguard Worker             case 4:
916*789431f2SAndroid Build Coastguard Worker                 ad_checksum = xor_block(ad_checksum, ta[3]);
917*789431f2SAndroid Build Coastguard Worker                 __fallthrough;
918*789431f2SAndroid Build Coastguard Worker             case 3:
919*789431f2SAndroid Build Coastguard Worker                 ad_checksum = xor_block(ad_checksum, ta[2]);
920*789431f2SAndroid Build Coastguard Worker                 __fallthrough;
921*789431f2SAndroid Build Coastguard Worker             case 2:
922*789431f2SAndroid Build Coastguard Worker                 ad_checksum = xor_block(ad_checksum, ta[1]);
923*789431f2SAndroid Build Coastguard Worker                 __fallthrough;
924*789431f2SAndroid Build Coastguard Worker             case 1:
925*789431f2SAndroid Build Coastguard Worker                 ad_checksum = xor_block(ad_checksum, ta[0]);
926*789431f2SAndroid Build Coastguard Worker             }
927*789431f2SAndroid Build Coastguard Worker             ctx->ad_checksum = ad_checksum;
928*789431f2SAndroid Build Coastguard Worker         }
929*789431f2SAndroid Build Coastguard Worker     }
930*789431f2SAndroid Build Coastguard Worker }
931*789431f2SAndroid Build Coastguard Worker 
932*789431f2SAndroid Build Coastguard Worker /* ----------------------------------------------------------------------- */
933*789431f2SAndroid Build Coastguard Worker 
ae_encrypt(ae_ctx * ctx,const void * nonce,const void * pt,int pt_len,const void * ad,int ad_len,void * ct,void * tag,int final)934*789431f2SAndroid Build Coastguard Worker int ae_encrypt(ae_ctx* ctx, const void* nonce, const void* pt, int pt_len, const void* ad,
935*789431f2SAndroid Build Coastguard Worker                int ad_len, void* ct, void* tag, int final) {
936*789431f2SAndroid Build Coastguard Worker     union {
937*789431f2SAndroid Build Coastguard Worker         uint32_t u32[4];
938*789431f2SAndroid Build Coastguard Worker         uint8_t u8[16];
939*789431f2SAndroid Build Coastguard Worker         block bl;
940*789431f2SAndroid Build Coastguard Worker     } tmp;
941*789431f2SAndroid Build Coastguard Worker     block offset, checksum;
942*789431f2SAndroid Build Coastguard Worker     unsigned i, k;
943*789431f2SAndroid Build Coastguard Worker     block* ctp = (block*)ct;
944*789431f2SAndroid Build Coastguard Worker     const block* ptp = (block*)pt;
945*789431f2SAndroid Build Coastguard Worker 
946*789431f2SAndroid Build Coastguard Worker     /* Non-null nonce means start of new message, init per-message values */
947*789431f2SAndroid Build Coastguard Worker     if (nonce) {
948*789431f2SAndroid Build Coastguard Worker         ctx->offset = gen_offset_from_nonce(ctx, nonce);
949*789431f2SAndroid Build Coastguard Worker         ctx->ad_offset = ctx->checksum = zero_block();
950*789431f2SAndroid Build Coastguard Worker         ctx->ad_blocks_processed = ctx->blocks_processed = 0;
951*789431f2SAndroid Build Coastguard Worker         if (ad_len >= 0)
952*789431f2SAndroid Build Coastguard Worker             ctx->ad_checksum = zero_block();
953*789431f2SAndroid Build Coastguard Worker     }
954*789431f2SAndroid Build Coastguard Worker 
955*789431f2SAndroid Build Coastguard Worker     /* Process associated data */
956*789431f2SAndroid Build Coastguard Worker     if (ad_len > 0)
957*789431f2SAndroid Build Coastguard Worker         process_ad(ctx, ad, ad_len, final);
958*789431f2SAndroid Build Coastguard Worker 
959*789431f2SAndroid Build Coastguard Worker     /* Encrypt plaintext data BPI blocks at a time */
960*789431f2SAndroid Build Coastguard Worker     offset = ctx->offset;
961*789431f2SAndroid Build Coastguard Worker     checksum = ctx->checksum;
962*789431f2SAndroid Build Coastguard Worker     i = pt_len / (BPI * 16);
963*789431f2SAndroid Build Coastguard Worker     if (i) {
964*789431f2SAndroid Build Coastguard Worker         block oa[BPI];
965*789431f2SAndroid Build Coastguard Worker         unsigned block_num = ctx->blocks_processed;
966*789431f2SAndroid Build Coastguard Worker         oa[BPI - 1] = offset;
967*789431f2SAndroid Build Coastguard Worker         do {
968*789431f2SAndroid Build Coastguard Worker             block ta[BPI];
969*789431f2SAndroid Build Coastguard Worker             block_num += BPI;
970*789431f2SAndroid Build Coastguard Worker             oa[0] = xor_block(oa[BPI - 1], ctx->L[0]);
971*789431f2SAndroid Build Coastguard Worker             ta[0] = xor_block(oa[0], ptp[0]);
972*789431f2SAndroid Build Coastguard Worker             checksum = xor_block(checksum, ptp[0]);
973*789431f2SAndroid Build Coastguard Worker             oa[1] = xor_block(oa[0], ctx->L[1]);
974*789431f2SAndroid Build Coastguard Worker             ta[1] = xor_block(oa[1], ptp[1]);
975*789431f2SAndroid Build Coastguard Worker             checksum = xor_block(checksum, ptp[1]);
976*789431f2SAndroid Build Coastguard Worker             oa[2] = xor_block(oa[1], ctx->L[0]);
977*789431f2SAndroid Build Coastguard Worker             ta[2] = xor_block(oa[2], ptp[2]);
978*789431f2SAndroid Build Coastguard Worker             checksum = xor_block(checksum, ptp[2]);
979*789431f2SAndroid Build Coastguard Worker #if BPI == 4
980*789431f2SAndroid Build Coastguard Worker             oa[3] = xor_block(oa[2], getL(ctx, ntz(block_num)));
981*789431f2SAndroid Build Coastguard Worker             ta[3] = xor_block(oa[3], ptp[3]);
982*789431f2SAndroid Build Coastguard Worker             checksum = xor_block(checksum, ptp[3]);
983*789431f2SAndroid Build Coastguard Worker #elif BPI == 8
984*789431f2SAndroid Build Coastguard Worker             oa[3] = xor_block(oa[2], ctx->L[2]);
985*789431f2SAndroid Build Coastguard Worker             ta[3] = xor_block(oa[3], ptp[3]);
986*789431f2SAndroid Build Coastguard Worker             checksum = xor_block(checksum, ptp[3]);
987*789431f2SAndroid Build Coastguard Worker             oa[4] = xor_block(oa[1], ctx->L[2]);
988*789431f2SAndroid Build Coastguard Worker             ta[4] = xor_block(oa[4], ptp[4]);
989*789431f2SAndroid Build Coastguard Worker             checksum = xor_block(checksum, ptp[4]);
990*789431f2SAndroid Build Coastguard Worker             oa[5] = xor_block(oa[0], ctx->L[2]);
991*789431f2SAndroid Build Coastguard Worker             ta[5] = xor_block(oa[5], ptp[5]);
992*789431f2SAndroid Build Coastguard Worker             checksum = xor_block(checksum, ptp[5]);
993*789431f2SAndroid Build Coastguard Worker             oa[6] = xor_block(oa[7], ctx->L[2]);
994*789431f2SAndroid Build Coastguard Worker             ta[6] = xor_block(oa[6], ptp[6]);
995*789431f2SAndroid Build Coastguard Worker             checksum = xor_block(checksum, ptp[6]);
996*789431f2SAndroid Build Coastguard Worker             oa[7] = xor_block(oa[6], getL(ctx, ntz(block_num)));
997*789431f2SAndroid Build Coastguard Worker             ta[7] = xor_block(oa[7], ptp[7]);
998*789431f2SAndroid Build Coastguard Worker             checksum = xor_block(checksum, ptp[7]);
999*789431f2SAndroid Build Coastguard Worker #endif
1000*789431f2SAndroid Build Coastguard Worker             AES_ecb_encrypt_blks(ta, BPI, &ctx->encrypt_key);
1001*789431f2SAndroid Build Coastguard Worker             ctp[0] = xor_block(ta[0], oa[0]);
1002*789431f2SAndroid Build Coastguard Worker             ctp[1] = xor_block(ta[1], oa[1]);
1003*789431f2SAndroid Build Coastguard Worker             ctp[2] = xor_block(ta[2], oa[2]);
1004*789431f2SAndroid Build Coastguard Worker             ctp[3] = xor_block(ta[3], oa[3]);
1005*789431f2SAndroid Build Coastguard Worker #if (BPI == 8)
1006*789431f2SAndroid Build Coastguard Worker             ctp[4] = xor_block(ta[4], oa[4]);
1007*789431f2SAndroid Build Coastguard Worker             ctp[5] = xor_block(ta[5], oa[5]);
1008*789431f2SAndroid Build Coastguard Worker             ctp[6] = xor_block(ta[6], oa[6]);
1009*789431f2SAndroid Build Coastguard Worker             ctp[7] = xor_block(ta[7], oa[7]);
1010*789431f2SAndroid Build Coastguard Worker #endif
1011*789431f2SAndroid Build Coastguard Worker             ptp += BPI;
1012*789431f2SAndroid Build Coastguard Worker             ctp += BPI;
1013*789431f2SAndroid Build Coastguard Worker         } while (--i);
1014*789431f2SAndroid Build Coastguard Worker         ctx->offset = offset = oa[BPI - 1];
1015*789431f2SAndroid Build Coastguard Worker         ctx->blocks_processed = block_num;
1016*789431f2SAndroid Build Coastguard Worker         ctx->checksum = checksum;
1017*789431f2SAndroid Build Coastguard Worker     }
1018*789431f2SAndroid Build Coastguard Worker 
1019*789431f2SAndroid Build Coastguard Worker     if (final) {
1020*789431f2SAndroid Build Coastguard Worker         block ta[BPI + 1], oa[BPI];
1021*789431f2SAndroid Build Coastguard Worker 
1022*789431f2SAndroid Build Coastguard Worker         /* Process remaining plaintext and compute its tag contribution    */
1023*789431f2SAndroid Build Coastguard Worker         unsigned remaining = ((unsigned)pt_len) % (BPI * 16);
1024*789431f2SAndroid Build Coastguard Worker         k = 0; /* How many blocks in ta[] need ECBing */
1025*789431f2SAndroid Build Coastguard Worker         if (remaining) {
1026*789431f2SAndroid Build Coastguard Worker #if (BPI == 8)
1027*789431f2SAndroid Build Coastguard Worker             if (remaining >= 64) {
1028*789431f2SAndroid Build Coastguard Worker                 oa[0] = xor_block(offset, ctx->L[0]);
1029*789431f2SAndroid Build Coastguard Worker                 ta[0] = xor_block(oa[0], ptp[0]);
1030*789431f2SAndroid Build Coastguard Worker                 checksum = xor_block(checksum, ptp[0]);
1031*789431f2SAndroid Build Coastguard Worker                 oa[1] = xor_block(oa[0], ctx->L[1]);
1032*789431f2SAndroid Build Coastguard Worker                 ta[1] = xor_block(oa[1], ptp[1]);
1033*789431f2SAndroid Build Coastguard Worker                 checksum = xor_block(checksum, ptp[1]);
1034*789431f2SAndroid Build Coastguard Worker                 oa[2] = xor_block(oa[1], ctx->L[0]);
1035*789431f2SAndroid Build Coastguard Worker                 ta[2] = xor_block(oa[2], ptp[2]);
1036*789431f2SAndroid Build Coastguard Worker                 checksum = xor_block(checksum, ptp[2]);
1037*789431f2SAndroid Build Coastguard Worker                 offset = oa[3] = xor_block(oa[2], ctx->L[2]);
1038*789431f2SAndroid Build Coastguard Worker                 ta[3] = xor_block(offset, ptp[3]);
1039*789431f2SAndroid Build Coastguard Worker                 checksum = xor_block(checksum, ptp[3]);
1040*789431f2SAndroid Build Coastguard Worker                 remaining -= 64;
1041*789431f2SAndroid Build Coastguard Worker                 k = 4;
1042*789431f2SAndroid Build Coastguard Worker             }
1043*789431f2SAndroid Build Coastguard Worker #endif
1044*789431f2SAndroid Build Coastguard Worker             if (remaining >= 32) {
1045*789431f2SAndroid Build Coastguard Worker                 oa[k] = xor_block(offset, ctx->L[0]);
1046*789431f2SAndroid Build Coastguard Worker                 ta[k] = xor_block(oa[k], ptp[k]);
1047*789431f2SAndroid Build Coastguard Worker                 checksum = xor_block(checksum, ptp[k]);
1048*789431f2SAndroid Build Coastguard Worker                 offset = oa[k + 1] = xor_block(oa[k], ctx->L[1]);
1049*789431f2SAndroid Build Coastguard Worker                 ta[k + 1] = xor_block(offset, ptp[k + 1]);
1050*789431f2SAndroid Build Coastguard Worker                 checksum = xor_block(checksum, ptp[k + 1]);
1051*789431f2SAndroid Build Coastguard Worker                 remaining -= 32;
1052*789431f2SAndroid Build Coastguard Worker                 k += 2;
1053*789431f2SAndroid Build Coastguard Worker             }
1054*789431f2SAndroid Build Coastguard Worker             if (remaining >= 16) {
1055*789431f2SAndroid Build Coastguard Worker                 offset = oa[k] = xor_block(offset, ctx->L[0]);
1056*789431f2SAndroid Build Coastguard Worker                 ta[k] = xor_block(offset, ptp[k]);
1057*789431f2SAndroid Build Coastguard Worker                 checksum = xor_block(checksum, ptp[k]);
1058*789431f2SAndroid Build Coastguard Worker                 remaining -= 16;
1059*789431f2SAndroid Build Coastguard Worker                 ++k;
1060*789431f2SAndroid Build Coastguard Worker             }
1061*789431f2SAndroid Build Coastguard Worker             if (remaining) {
1062*789431f2SAndroid Build Coastguard Worker                 tmp.bl = zero_block();
1063*789431f2SAndroid Build Coastguard Worker                 memcpy(tmp.u8, ptp + k, remaining);
1064*789431f2SAndroid Build Coastguard Worker                 tmp.u8[remaining] = (unsigned char)0x80u;
1065*789431f2SAndroid Build Coastguard Worker                 checksum = xor_block(checksum, tmp.bl);
1066*789431f2SAndroid Build Coastguard Worker                 ta[k] = offset = xor_block(offset, ctx->Lstar);
1067*789431f2SAndroid Build Coastguard Worker                 ++k;
1068*789431f2SAndroid Build Coastguard Worker             }
1069*789431f2SAndroid Build Coastguard Worker         }
1070*789431f2SAndroid Build Coastguard Worker         offset = xor_block(offset, ctx->Ldollar); /* Part of tag gen */
1071*789431f2SAndroid Build Coastguard Worker         ta[k] = xor_block(offset, checksum);      /* Part of tag gen */
1072*789431f2SAndroid Build Coastguard Worker         AES_ecb_encrypt_blks(ta, k + 1, &ctx->encrypt_key);
1073*789431f2SAndroid Build Coastguard Worker         offset = xor_block(ta[k], ctx->ad_checksum); /* Part of tag gen */
1074*789431f2SAndroid Build Coastguard Worker         if (remaining) {
1075*789431f2SAndroid Build Coastguard Worker             --k;
1076*789431f2SAndroid Build Coastguard Worker             tmp.bl = xor_block(tmp.bl, ta[k]);
1077*789431f2SAndroid Build Coastguard Worker             memcpy(ctp + k, tmp.u8, remaining);
1078*789431f2SAndroid Build Coastguard Worker         }
1079*789431f2SAndroid Build Coastguard Worker         switch (k) {
1080*789431f2SAndroid Build Coastguard Worker #if (BPI == 8)
1081*789431f2SAndroid Build Coastguard Worker         case 7:
1082*789431f2SAndroid Build Coastguard Worker             ctp[6] = xor_block(ta[6], oa[6]);
1083*789431f2SAndroid Build Coastguard Worker             __fallthrough;
1084*789431f2SAndroid Build Coastguard Worker         case 6:
1085*789431f2SAndroid Build Coastguard Worker             ctp[5] = xor_block(ta[5], oa[5]);
1086*789431f2SAndroid Build Coastguard Worker             __fallthrough;
1087*789431f2SAndroid Build Coastguard Worker         case 5:
1088*789431f2SAndroid Build Coastguard Worker             ctp[4] = xor_block(ta[4], oa[4]);
1089*789431f2SAndroid Build Coastguard Worker             __fallthrough;
1090*789431f2SAndroid Build Coastguard Worker         case 4:
1091*789431f2SAndroid Build Coastguard Worker             ctp[3] = xor_block(ta[3], oa[3]);
1092*789431f2SAndroid Build Coastguard Worker             __fallthrough;
1093*789431f2SAndroid Build Coastguard Worker #endif
1094*789431f2SAndroid Build Coastguard Worker         case 3:
1095*789431f2SAndroid Build Coastguard Worker             ctp[2] = xor_block(ta[2], oa[2]);
1096*789431f2SAndroid Build Coastguard Worker             __fallthrough;
1097*789431f2SAndroid Build Coastguard Worker         case 2:
1098*789431f2SAndroid Build Coastguard Worker             ctp[1] = xor_block(ta[1], oa[1]);
1099*789431f2SAndroid Build Coastguard Worker             __fallthrough;
1100*789431f2SAndroid Build Coastguard Worker         case 1:
1101*789431f2SAndroid Build Coastguard Worker             ctp[0] = xor_block(ta[0], oa[0]);
1102*789431f2SAndroid Build Coastguard Worker         }
1103*789431f2SAndroid Build Coastguard Worker 
1104*789431f2SAndroid Build Coastguard Worker         /* Tag is placed at the correct location
1105*789431f2SAndroid Build Coastguard Worker          */
1106*789431f2SAndroid Build Coastguard Worker         if (tag) {
1107*789431f2SAndroid Build Coastguard Worker #if (OCB_TAG_LEN == 16)
1108*789431f2SAndroid Build Coastguard Worker             *(block*)tag = offset;
1109*789431f2SAndroid Build Coastguard Worker #elif(OCB_TAG_LEN > 0)
1110*789431f2SAndroid Build Coastguard Worker             memcpy((char*)tag, &offset, OCB_TAG_LEN);
1111*789431f2SAndroid Build Coastguard Worker #else
1112*789431f2SAndroid Build Coastguard Worker             memcpy((char*)tag, &offset, ctx->tag_len);
1113*789431f2SAndroid Build Coastguard Worker #endif
1114*789431f2SAndroid Build Coastguard Worker         } else {
1115*789431f2SAndroid Build Coastguard Worker #if (OCB_TAG_LEN > 0)
1116*789431f2SAndroid Build Coastguard Worker             memcpy((char*)ct + pt_len, &offset, OCB_TAG_LEN);
1117*789431f2SAndroid Build Coastguard Worker             pt_len += OCB_TAG_LEN;
1118*789431f2SAndroid Build Coastguard Worker #else
1119*789431f2SAndroid Build Coastguard Worker             memcpy((char*)ct + pt_len, &offset, ctx->tag_len);
1120*789431f2SAndroid Build Coastguard Worker             pt_len += ctx->tag_len;
1121*789431f2SAndroid Build Coastguard Worker #endif
1122*789431f2SAndroid Build Coastguard Worker         }
1123*789431f2SAndroid Build Coastguard Worker     }
1124*789431f2SAndroid Build Coastguard Worker     return (int)pt_len;
1125*789431f2SAndroid Build Coastguard Worker }
1126*789431f2SAndroid Build Coastguard Worker 
1127*789431f2SAndroid Build Coastguard Worker /* ----------------------------------------------------------------------- */
1128*789431f2SAndroid Build Coastguard Worker 
1129*789431f2SAndroid Build Coastguard Worker /* Compare two regions of memory, taking a constant amount of time for a
1130*789431f2SAndroid Build Coastguard Worker    given buffer size -- under certain assumptions about the compiler
1131*789431f2SAndroid Build Coastguard Worker    and machine, of course.
1132*789431f2SAndroid Build Coastguard Worker 
1133*789431f2SAndroid Build Coastguard Worker    Use this to avoid timing side-channel attacks.
1134*789431f2SAndroid Build Coastguard Worker 
1135*789431f2SAndroid Build Coastguard Worker    Returns 0 for memory regions with equal contents; non-zero otherwise. */
constant_time_memcmp(const void * av,const void * bv,size_t n)1136*789431f2SAndroid Build Coastguard Worker static int constant_time_memcmp(const void* av, const void* bv, size_t n) {
1137*789431f2SAndroid Build Coastguard Worker     const uint8_t* a = (const uint8_t*)av;
1138*789431f2SAndroid Build Coastguard Worker     const uint8_t* b = (const uint8_t*)bv;
1139*789431f2SAndroid Build Coastguard Worker     uint8_t result = 0;
1140*789431f2SAndroid Build Coastguard Worker     size_t i;
1141*789431f2SAndroid Build Coastguard Worker 
1142*789431f2SAndroid Build Coastguard Worker     for (i = 0; i < n; i++) {
1143*789431f2SAndroid Build Coastguard Worker         result |= *a ^ *b;
1144*789431f2SAndroid Build Coastguard Worker         a++;
1145*789431f2SAndroid Build Coastguard Worker         b++;
1146*789431f2SAndroid Build Coastguard Worker     }
1147*789431f2SAndroid Build Coastguard Worker 
1148*789431f2SAndroid Build Coastguard Worker     return (int)result;
1149*789431f2SAndroid Build Coastguard Worker }
1150*789431f2SAndroid Build Coastguard Worker 
ae_decrypt(ae_ctx * ctx,const void * nonce,const void * ct,int ct_len,const void * ad,int ad_len,void * pt,const void * tag,int final)1151*789431f2SAndroid Build Coastguard Worker int ae_decrypt(ae_ctx* ctx, const void* nonce, const void* ct, int ct_len, const void* ad,
1152*789431f2SAndroid Build Coastguard Worker                int ad_len, void* pt, const void* tag, int final) {
1153*789431f2SAndroid Build Coastguard Worker     union {
1154*789431f2SAndroid Build Coastguard Worker         uint32_t u32[4];
1155*789431f2SAndroid Build Coastguard Worker         uint8_t u8[16];
1156*789431f2SAndroid Build Coastguard Worker         block bl;
1157*789431f2SAndroid Build Coastguard Worker     } tmp;
1158*789431f2SAndroid Build Coastguard Worker     block offset, checksum;
1159*789431f2SAndroid Build Coastguard Worker     unsigned i, k;
1160*789431f2SAndroid Build Coastguard Worker     block* ctp = (block*)ct;
1161*789431f2SAndroid Build Coastguard Worker     block* ptp = (block*)pt;
1162*789431f2SAndroid Build Coastguard Worker 
1163*789431f2SAndroid Build Coastguard Worker     /* Reduce ct_len tag bundled in ct */
1164*789431f2SAndroid Build Coastguard Worker     if ((final) && (!tag))
1165*789431f2SAndroid Build Coastguard Worker #if (OCB_TAG_LEN > 0)
1166*789431f2SAndroid Build Coastguard Worker         ct_len -= OCB_TAG_LEN;
1167*789431f2SAndroid Build Coastguard Worker #else
1168*789431f2SAndroid Build Coastguard Worker         ct_len -= ctx->tag_len;
1169*789431f2SAndroid Build Coastguard Worker #endif
1170*789431f2SAndroid Build Coastguard Worker 
1171*789431f2SAndroid Build Coastguard Worker     /* Non-null nonce means start of new message, init per-message values */
1172*789431f2SAndroid Build Coastguard Worker     if (nonce) {
1173*789431f2SAndroid Build Coastguard Worker         ctx->offset = gen_offset_from_nonce(ctx, nonce);
1174*789431f2SAndroid Build Coastguard Worker         ctx->ad_offset = ctx->checksum = zero_block();
1175*789431f2SAndroid Build Coastguard Worker         ctx->ad_blocks_processed = ctx->blocks_processed = 0;
1176*789431f2SAndroid Build Coastguard Worker         if (ad_len >= 0)
1177*789431f2SAndroid Build Coastguard Worker             ctx->ad_checksum = zero_block();
1178*789431f2SAndroid Build Coastguard Worker     }
1179*789431f2SAndroid Build Coastguard Worker 
1180*789431f2SAndroid Build Coastguard Worker     /* Process associated data */
1181*789431f2SAndroid Build Coastguard Worker     if (ad_len > 0)
1182*789431f2SAndroid Build Coastguard Worker         process_ad(ctx, ad, ad_len, final);
1183*789431f2SAndroid Build Coastguard Worker 
1184*789431f2SAndroid Build Coastguard Worker     /* Encrypt plaintext data BPI blocks at a time */
1185*789431f2SAndroid Build Coastguard Worker     offset = ctx->offset;
1186*789431f2SAndroid Build Coastguard Worker     checksum = ctx->checksum;
1187*789431f2SAndroid Build Coastguard Worker     i = ct_len / (BPI * 16);
1188*789431f2SAndroid Build Coastguard Worker     if (i) {
1189*789431f2SAndroid Build Coastguard Worker         block oa[BPI];
1190*789431f2SAndroid Build Coastguard Worker         unsigned block_num = ctx->blocks_processed;
1191*789431f2SAndroid Build Coastguard Worker         oa[BPI - 1] = offset;
1192*789431f2SAndroid Build Coastguard Worker         do {
1193*789431f2SAndroid Build Coastguard Worker             block ta[BPI];
1194*789431f2SAndroid Build Coastguard Worker             block_num += BPI;
1195*789431f2SAndroid Build Coastguard Worker             oa[0] = xor_block(oa[BPI - 1], ctx->L[0]);
1196*789431f2SAndroid Build Coastguard Worker             ta[0] = xor_block(oa[0], ctp[0]);
1197*789431f2SAndroid Build Coastguard Worker             oa[1] = xor_block(oa[0], ctx->L[1]);
1198*789431f2SAndroid Build Coastguard Worker             ta[1] = xor_block(oa[1], ctp[1]);
1199*789431f2SAndroid Build Coastguard Worker             oa[2] = xor_block(oa[1], ctx->L[0]);
1200*789431f2SAndroid Build Coastguard Worker             ta[2] = xor_block(oa[2], ctp[2]);
1201*789431f2SAndroid Build Coastguard Worker #if BPI == 4
1202*789431f2SAndroid Build Coastguard Worker             oa[3] = xor_block(oa[2], getL(ctx, ntz(block_num)));
1203*789431f2SAndroid Build Coastguard Worker             ta[3] = xor_block(oa[3], ctp[3]);
1204*789431f2SAndroid Build Coastguard Worker #elif BPI == 8
1205*789431f2SAndroid Build Coastguard Worker             oa[3] = xor_block(oa[2], ctx->L[2]);
1206*789431f2SAndroid Build Coastguard Worker             ta[3] = xor_block(oa[3], ctp[3]);
1207*789431f2SAndroid Build Coastguard Worker             oa[4] = xor_block(oa[1], ctx->L[2]);
1208*789431f2SAndroid Build Coastguard Worker             ta[4] = xor_block(oa[4], ctp[4]);
1209*789431f2SAndroid Build Coastguard Worker             oa[5] = xor_block(oa[0], ctx->L[2]);
1210*789431f2SAndroid Build Coastguard Worker             ta[5] = xor_block(oa[5], ctp[5]);
1211*789431f2SAndroid Build Coastguard Worker             oa[6] = xor_block(oa[7], ctx->L[2]);
1212*789431f2SAndroid Build Coastguard Worker             ta[6] = xor_block(oa[6], ctp[6]);
1213*789431f2SAndroid Build Coastguard Worker             oa[7] = xor_block(oa[6], getL(ctx, ntz(block_num)));
1214*789431f2SAndroid Build Coastguard Worker             ta[7] = xor_block(oa[7], ctp[7]);
1215*789431f2SAndroid Build Coastguard Worker #endif
1216*789431f2SAndroid Build Coastguard Worker             AES_ecb_decrypt_blks(ta, BPI, &ctx->decrypt_key);
1217*789431f2SAndroid Build Coastguard Worker             ptp[0] = xor_block(ta[0], oa[0]);
1218*789431f2SAndroid Build Coastguard Worker             checksum = xor_block(checksum, ptp[0]);
1219*789431f2SAndroid Build Coastguard Worker             ptp[1] = xor_block(ta[1], oa[1]);
1220*789431f2SAndroid Build Coastguard Worker             checksum = xor_block(checksum, ptp[1]);
1221*789431f2SAndroid Build Coastguard Worker             ptp[2] = xor_block(ta[2], oa[2]);
1222*789431f2SAndroid Build Coastguard Worker             checksum = xor_block(checksum, ptp[2]);
1223*789431f2SAndroid Build Coastguard Worker             ptp[3] = xor_block(ta[3], oa[3]);
1224*789431f2SAndroid Build Coastguard Worker             checksum = xor_block(checksum, ptp[3]);
1225*789431f2SAndroid Build Coastguard Worker #if (BPI == 8)
1226*789431f2SAndroid Build Coastguard Worker             ptp[4] = xor_block(ta[4], oa[4]);
1227*789431f2SAndroid Build Coastguard Worker             checksum = xor_block(checksum, ptp[4]);
1228*789431f2SAndroid Build Coastguard Worker             ptp[5] = xor_block(ta[5], oa[5]);
1229*789431f2SAndroid Build Coastguard Worker             checksum = xor_block(checksum, ptp[5]);
1230*789431f2SAndroid Build Coastguard Worker             ptp[6] = xor_block(ta[6], oa[6]);
1231*789431f2SAndroid Build Coastguard Worker             checksum = xor_block(checksum, ptp[6]);
1232*789431f2SAndroid Build Coastguard Worker             ptp[7] = xor_block(ta[7], oa[7]);
1233*789431f2SAndroid Build Coastguard Worker             checksum = xor_block(checksum, ptp[7]);
1234*789431f2SAndroid Build Coastguard Worker #endif
1235*789431f2SAndroid Build Coastguard Worker             ptp += BPI;
1236*789431f2SAndroid Build Coastguard Worker             ctp += BPI;
1237*789431f2SAndroid Build Coastguard Worker         } while (--i);
1238*789431f2SAndroid Build Coastguard Worker         ctx->offset = offset = oa[BPI - 1];
1239*789431f2SAndroid Build Coastguard Worker         ctx->blocks_processed = block_num;
1240*789431f2SAndroid Build Coastguard Worker         ctx->checksum = checksum;
1241*789431f2SAndroid Build Coastguard Worker     }
1242*789431f2SAndroid Build Coastguard Worker 
1243*789431f2SAndroid Build Coastguard Worker     if (final) {
1244*789431f2SAndroid Build Coastguard Worker         block ta[BPI + 1], oa[BPI];
1245*789431f2SAndroid Build Coastguard Worker 
1246*789431f2SAndroid Build Coastguard Worker         /* Process remaining plaintext and compute its tag contribution    */
1247*789431f2SAndroid Build Coastguard Worker         unsigned remaining = ((unsigned)ct_len) % (BPI * 16);
1248*789431f2SAndroid Build Coastguard Worker         k = 0; /* How many blocks in ta[] need ECBing */
1249*789431f2SAndroid Build Coastguard Worker         if (remaining) {
1250*789431f2SAndroid Build Coastguard Worker #if (BPI == 8)
1251*789431f2SAndroid Build Coastguard Worker             if (remaining >= 64) {
1252*789431f2SAndroid Build Coastguard Worker                 oa[0] = xor_block(offset, ctx->L[0]);
1253*789431f2SAndroid Build Coastguard Worker                 ta[0] = xor_block(oa[0], ctp[0]);
1254*789431f2SAndroid Build Coastguard Worker                 oa[1] = xor_block(oa[0], ctx->L[1]);
1255*789431f2SAndroid Build Coastguard Worker                 ta[1] = xor_block(oa[1], ctp[1]);
1256*789431f2SAndroid Build Coastguard Worker                 oa[2] = xor_block(oa[1], ctx->L[0]);
1257*789431f2SAndroid Build Coastguard Worker                 ta[2] = xor_block(oa[2], ctp[2]);
1258*789431f2SAndroid Build Coastguard Worker                 offset = oa[3] = xor_block(oa[2], ctx->L[2]);
1259*789431f2SAndroid Build Coastguard Worker                 ta[3] = xor_block(offset, ctp[3]);
1260*789431f2SAndroid Build Coastguard Worker                 remaining -= 64;
1261*789431f2SAndroid Build Coastguard Worker                 k = 4;
1262*789431f2SAndroid Build Coastguard Worker             }
1263*789431f2SAndroid Build Coastguard Worker #endif
1264*789431f2SAndroid Build Coastguard Worker             if (remaining >= 32) {
1265*789431f2SAndroid Build Coastguard Worker                 oa[k] = xor_block(offset, ctx->L[0]);
1266*789431f2SAndroid Build Coastguard Worker                 ta[k] = xor_block(oa[k], ctp[k]);
1267*789431f2SAndroid Build Coastguard Worker                 offset = oa[k + 1] = xor_block(oa[k], ctx->L[1]);
1268*789431f2SAndroid Build Coastguard Worker                 ta[k + 1] = xor_block(offset, ctp[k + 1]);
1269*789431f2SAndroid Build Coastguard Worker                 remaining -= 32;
1270*789431f2SAndroid Build Coastguard Worker                 k += 2;
1271*789431f2SAndroid Build Coastguard Worker             }
1272*789431f2SAndroid Build Coastguard Worker             if (remaining >= 16) {
1273*789431f2SAndroid Build Coastguard Worker                 offset = oa[k] = xor_block(offset, ctx->L[0]);
1274*789431f2SAndroid Build Coastguard Worker                 ta[k] = xor_block(offset, ctp[k]);
1275*789431f2SAndroid Build Coastguard Worker                 remaining -= 16;
1276*789431f2SAndroid Build Coastguard Worker                 ++k;
1277*789431f2SAndroid Build Coastguard Worker             }
1278*789431f2SAndroid Build Coastguard Worker             if (remaining) {
1279*789431f2SAndroid Build Coastguard Worker                 block pad;
1280*789431f2SAndroid Build Coastguard Worker                 offset = xor_block(offset, ctx->Lstar);
1281*789431f2SAndroid Build Coastguard Worker                 AES_encrypt((unsigned char*)&offset, tmp.u8, &ctx->encrypt_key);
1282*789431f2SAndroid Build Coastguard Worker                 pad = tmp.bl;
1283*789431f2SAndroid Build Coastguard Worker                 memcpy(tmp.u8, ctp + k, remaining);
1284*789431f2SAndroid Build Coastguard Worker                 tmp.bl = xor_block(tmp.bl, pad);
1285*789431f2SAndroid Build Coastguard Worker                 tmp.u8[remaining] = (unsigned char)0x80u;
1286*789431f2SAndroid Build Coastguard Worker                 memcpy(ptp + k, tmp.u8, remaining);
1287*789431f2SAndroid Build Coastguard Worker                 checksum = xor_block(checksum, tmp.bl);
1288*789431f2SAndroid Build Coastguard Worker             }
1289*789431f2SAndroid Build Coastguard Worker         }
1290*789431f2SAndroid Build Coastguard Worker         AES_ecb_decrypt_blks(ta, k, &ctx->decrypt_key);
1291*789431f2SAndroid Build Coastguard Worker         switch (k) {
1292*789431f2SAndroid Build Coastguard Worker #if (BPI == 8)
1293*789431f2SAndroid Build Coastguard Worker         case 7:
1294*789431f2SAndroid Build Coastguard Worker             ptp[6] = xor_block(ta[6], oa[6]);
1295*789431f2SAndroid Build Coastguard Worker             checksum = xor_block(checksum, ptp[6]);
1296*789431f2SAndroid Build Coastguard Worker             __fallthrough;
1297*789431f2SAndroid Build Coastguard Worker         case 6:
1298*789431f2SAndroid Build Coastguard Worker             ptp[5] = xor_block(ta[5], oa[5]);
1299*789431f2SAndroid Build Coastguard Worker             checksum = xor_block(checksum, ptp[5]);
1300*789431f2SAndroid Build Coastguard Worker             __fallthrough;
1301*789431f2SAndroid Build Coastguard Worker         case 5:
1302*789431f2SAndroid Build Coastguard Worker             ptp[4] = xor_block(ta[4], oa[4]);
1303*789431f2SAndroid Build Coastguard Worker             checksum = xor_block(checksum, ptp[4]);
1304*789431f2SAndroid Build Coastguard Worker             __fallthrough;
1305*789431f2SAndroid Build Coastguard Worker         case 4:
1306*789431f2SAndroid Build Coastguard Worker             ptp[3] = xor_block(ta[3], oa[3]);
1307*789431f2SAndroid Build Coastguard Worker             checksum = xor_block(checksum, ptp[3]);
1308*789431f2SAndroid Build Coastguard Worker             __fallthrough;
1309*789431f2SAndroid Build Coastguard Worker #endif
1310*789431f2SAndroid Build Coastguard Worker         case 3:
1311*789431f2SAndroid Build Coastguard Worker             ptp[2] = xor_block(ta[2], oa[2]);
1312*789431f2SAndroid Build Coastguard Worker             checksum = xor_block(checksum, ptp[2]);
1313*789431f2SAndroid Build Coastguard Worker             __fallthrough;
1314*789431f2SAndroid Build Coastguard Worker         case 2:
1315*789431f2SAndroid Build Coastguard Worker             ptp[1] = xor_block(ta[1], oa[1]);
1316*789431f2SAndroid Build Coastguard Worker             checksum = xor_block(checksum, ptp[1]);
1317*789431f2SAndroid Build Coastguard Worker             __fallthrough;
1318*789431f2SAndroid Build Coastguard Worker         case 1:
1319*789431f2SAndroid Build Coastguard Worker             ptp[0] = xor_block(ta[0], oa[0]);
1320*789431f2SAndroid Build Coastguard Worker             checksum = xor_block(checksum, ptp[0]);
1321*789431f2SAndroid Build Coastguard Worker         }
1322*789431f2SAndroid Build Coastguard Worker 
1323*789431f2SAndroid Build Coastguard Worker         /* Calculate expected tag */
1324*789431f2SAndroid Build Coastguard Worker         offset = xor_block(offset, ctx->Ldollar);
1325*789431f2SAndroid Build Coastguard Worker         tmp.bl = xor_block(offset, checksum);
1326*789431f2SAndroid Build Coastguard Worker         AES_encrypt(tmp.u8, tmp.u8, &ctx->encrypt_key);
1327*789431f2SAndroid Build Coastguard Worker         tmp.bl = xor_block(tmp.bl, ctx->ad_checksum); /* Full tag */
1328*789431f2SAndroid Build Coastguard Worker 
1329*789431f2SAndroid Build Coastguard Worker         /* Compare with proposed tag, change ct_len if invalid */
1330*789431f2SAndroid Build Coastguard Worker         if ((OCB_TAG_LEN == 16) && tag) {
1331*789431f2SAndroid Build Coastguard Worker             if (unequal_blocks(tmp.bl, *(block*)tag))
1332*789431f2SAndroid Build Coastguard Worker                 ct_len = AE_INVALID;
1333*789431f2SAndroid Build Coastguard Worker         } else {
1334*789431f2SAndroid Build Coastguard Worker #if (OCB_TAG_LEN > 0)
1335*789431f2SAndroid Build Coastguard Worker             int len = OCB_TAG_LEN;
1336*789431f2SAndroid Build Coastguard Worker #else
1337*789431f2SAndroid Build Coastguard Worker             int len = ctx->tag_len;
1338*789431f2SAndroid Build Coastguard Worker #endif
1339*789431f2SAndroid Build Coastguard Worker             if (tag) {
1340*789431f2SAndroid Build Coastguard Worker                 if (constant_time_memcmp(tag, tmp.u8, len) != 0)
1341*789431f2SAndroid Build Coastguard Worker                     ct_len = AE_INVALID;
1342*789431f2SAndroid Build Coastguard Worker             } else {
1343*789431f2SAndroid Build Coastguard Worker                 if (constant_time_memcmp((char*)ct + ct_len, tmp.u8, len) != 0)
1344*789431f2SAndroid Build Coastguard Worker                     ct_len = AE_INVALID;
1345*789431f2SAndroid Build Coastguard Worker             }
1346*789431f2SAndroid Build Coastguard Worker         }
1347*789431f2SAndroid Build Coastguard Worker     }
1348*789431f2SAndroid Build Coastguard Worker     return ct_len;
1349*789431f2SAndroid Build Coastguard Worker }
1350*789431f2SAndroid Build Coastguard Worker 
1351*789431f2SAndroid Build Coastguard Worker /* ----------------------------------------------------------------------- */
1352*789431f2SAndroid Build Coastguard Worker /* Simple test program                                                     */
1353*789431f2SAndroid Build Coastguard Worker /* ----------------------------------------------------------------------- */
1354*789431f2SAndroid Build Coastguard Worker 
1355*789431f2SAndroid Build Coastguard Worker #if 0
1356*789431f2SAndroid Build Coastguard Worker 
1357*789431f2SAndroid Build Coastguard Worker #include <stdio.h>
1358*789431f2SAndroid Build Coastguard Worker #include <time.h>
1359*789431f2SAndroid Build Coastguard Worker 
1360*789431f2SAndroid Build Coastguard Worker #if __GNUC__
1361*789431f2SAndroid Build Coastguard Worker #define ALIGN(n) __attribute__((aligned(n)))
1362*789431f2SAndroid Build Coastguard Worker #elif _MSC_VER
1363*789431f2SAndroid Build Coastguard Worker #define ALIGN(n) __declspec(align(n))
1364*789431f2SAndroid Build Coastguard Worker #else /* Not GNU/Microsoft: delete alignment uses.     */
1365*789431f2SAndroid Build Coastguard Worker #define ALIGN(n)
1366*789431f2SAndroid Build Coastguard Worker #endif
1367*789431f2SAndroid Build Coastguard Worker 
1368*789431f2SAndroid Build Coastguard Worker static void pbuf(void *p, unsigned len, const void *s)
1369*789431f2SAndroid Build Coastguard Worker {
1370*789431f2SAndroid Build Coastguard Worker     unsigned i;
1371*789431f2SAndroid Build Coastguard Worker     if (s)
1372*789431f2SAndroid Build Coastguard Worker         printf("%s", (char *)s);
1373*789431f2SAndroid Build Coastguard Worker     for (i = 0; i < len; i++)
1374*789431f2SAndroid Build Coastguard Worker         printf("%02X", (unsigned)(((unsigned char *)p)[i]));
1375*789431f2SAndroid Build Coastguard Worker     printf("\n");
1376*789431f2SAndroid Build Coastguard Worker }
1377*789431f2SAndroid Build Coastguard Worker 
1378*789431f2SAndroid Build Coastguard Worker static void vectors(ae_ctx *ctx, int len)
1379*789431f2SAndroid Build Coastguard Worker {
1380*789431f2SAndroid Build Coastguard Worker     ALIGN(16) char pt[128];
1381*789431f2SAndroid Build Coastguard Worker     ALIGN(16) char ct[144];
1382*789431f2SAndroid Build Coastguard Worker     ALIGN(16) char nonce[] = {0,1,2,3,4,5,6,7,8,9,10,11};
1383*789431f2SAndroid Build Coastguard Worker     int i;
1384*789431f2SAndroid Build Coastguard Worker     for (i=0; i < 128; i++) pt[i] = i;
1385*789431f2SAndroid Build Coastguard Worker     i = ae_encrypt(ctx,nonce,pt,len,pt,len,ct,NULL,AE_FINALIZE);
1386*789431f2SAndroid Build Coastguard Worker     printf("P=%d,A=%d: ",len,len); pbuf(ct, i, NULL);
1387*789431f2SAndroid Build Coastguard Worker     i = ae_encrypt(ctx,nonce,pt,0,pt,len,ct,NULL,AE_FINALIZE);
1388*789431f2SAndroid Build Coastguard Worker     printf("P=%d,A=%d: ",0,len); pbuf(ct, i, NULL);
1389*789431f2SAndroid Build Coastguard Worker     i = ae_encrypt(ctx,nonce,pt,len,pt,0,ct,NULL,AE_FINALIZE);
1390*789431f2SAndroid Build Coastguard Worker     printf("P=%d,A=%d: ",len,0); pbuf(ct, i, NULL);
1391*789431f2SAndroid Build Coastguard Worker }
1392*789431f2SAndroid Build Coastguard Worker 
1393*789431f2SAndroid Build Coastguard Worker void validate()
1394*789431f2SAndroid Build Coastguard Worker {
1395*789431f2SAndroid Build Coastguard Worker     ALIGN(16) char pt[1024];
1396*789431f2SAndroid Build Coastguard Worker     ALIGN(16) char ct[1024];
1397*789431f2SAndroid Build Coastguard Worker     ALIGN(16) char tag[16];
1398*789431f2SAndroid Build Coastguard Worker     ALIGN(16) char nonce[12] = {0,};
1399*789431f2SAndroid Build Coastguard Worker     ALIGN(16) char key[32] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31};
1400*789431f2SAndroid Build Coastguard Worker     ae_ctx ctx;
1401*789431f2SAndroid Build Coastguard Worker     char *val_buf, *next;
1402*789431f2SAndroid Build Coastguard Worker     int i, len;
1403*789431f2SAndroid Build Coastguard Worker 
1404*789431f2SAndroid Build Coastguard Worker     val_buf = (char *)malloc(22400 + 16);
1405*789431f2SAndroid Build Coastguard Worker     next = val_buf = (char *)(((size_t)val_buf + 16) & ~((size_t)15));
1406*789431f2SAndroid Build Coastguard Worker 
1407*789431f2SAndroid Build Coastguard Worker     if (0) {
1408*789431f2SAndroid Build Coastguard Worker 		ae_init(&ctx, key, 16, 12, 16);
1409*789431f2SAndroid Build Coastguard Worker 		/* pbuf(&ctx, sizeof(ctx), "CTX: "); */
1410*789431f2SAndroid Build Coastguard Worker 		vectors(&ctx,0);
1411*789431f2SAndroid Build Coastguard Worker 		vectors(&ctx,8);
1412*789431f2SAndroid Build Coastguard Worker 		vectors(&ctx,16);
1413*789431f2SAndroid Build Coastguard Worker 		vectors(&ctx,24);
1414*789431f2SAndroid Build Coastguard Worker 		vectors(&ctx,32);
1415*789431f2SAndroid Build Coastguard Worker 		vectors(&ctx,40);
1416*789431f2SAndroid Build Coastguard Worker     }
1417*789431f2SAndroid Build Coastguard Worker 
1418*789431f2SAndroid Build Coastguard Worker     memset(key,0,32);
1419*789431f2SAndroid Build Coastguard Worker     memset(pt,0,128);
1420*789431f2SAndroid Build Coastguard Worker     ae_init(&ctx, key, OCB_KEY_LEN, 12, OCB_TAG_LEN);
1421*789431f2SAndroid Build Coastguard Worker 
1422*789431f2SAndroid Build Coastguard Worker     /* RFC Vector test */
1423*789431f2SAndroid Build Coastguard Worker     for (i = 0; i < 128; i++) {
1424*789431f2SAndroid Build Coastguard Worker         int first = ((i/3)/(BPI*16))*(BPI*16);
1425*789431f2SAndroid Build Coastguard Worker         int second = first;
1426*789431f2SAndroid Build Coastguard Worker         int third = i - (first + second);
1427*789431f2SAndroid Build Coastguard Worker 
1428*789431f2SAndroid Build Coastguard Worker         nonce[11] = i;
1429*789431f2SAndroid Build Coastguard Worker 
1430*789431f2SAndroid Build Coastguard Worker         if (0) {
1431*789431f2SAndroid Build Coastguard Worker             ae_encrypt(&ctx,nonce,pt,i,pt,i,ct,NULL,AE_FINALIZE);
1432*789431f2SAndroid Build Coastguard Worker             memcpy(next,ct,(size_t)i+OCB_TAG_LEN);
1433*789431f2SAndroid Build Coastguard Worker             next = next+i+OCB_TAG_LEN;
1434*789431f2SAndroid Build Coastguard Worker 
1435*789431f2SAndroid Build Coastguard Worker             ae_encrypt(&ctx,nonce,pt,i,pt,0,ct,NULL,AE_FINALIZE);
1436*789431f2SAndroid Build Coastguard Worker             memcpy(next,ct,(size_t)i+OCB_TAG_LEN);
1437*789431f2SAndroid Build Coastguard Worker             next = next+i+OCB_TAG_LEN;
1438*789431f2SAndroid Build Coastguard Worker 
1439*789431f2SAndroid Build Coastguard Worker             ae_encrypt(&ctx,nonce,pt,0,pt,i,ct,NULL,AE_FINALIZE);
1440*789431f2SAndroid Build Coastguard Worker             memcpy(next,ct,OCB_TAG_LEN);
1441*789431f2SAndroid Build Coastguard Worker             next = next+OCB_TAG_LEN;
1442*789431f2SAndroid Build Coastguard Worker         } else {
1443*789431f2SAndroid Build Coastguard Worker             ae_encrypt(&ctx,nonce,pt,first,pt,first,ct,NULL,AE_PENDING);
1444*789431f2SAndroid Build Coastguard Worker             ae_encrypt(&ctx,NULL,pt+first,second,pt+first,second,ct+first,NULL,AE_PENDING);
1445*789431f2SAndroid Build Coastguard Worker             ae_encrypt(&ctx,NULL,pt+first+second,third,pt+first+second,third,ct+first+second,NULL,AE_FINALIZE);
1446*789431f2SAndroid Build Coastguard Worker             memcpy(next,ct,(size_t)i+OCB_TAG_LEN);
1447*789431f2SAndroid Build Coastguard Worker             next = next+i+OCB_TAG_LEN;
1448*789431f2SAndroid Build Coastguard Worker 
1449*789431f2SAndroid Build Coastguard Worker             ae_encrypt(&ctx,nonce,pt,first,pt,0,ct,NULL,AE_PENDING);
1450*789431f2SAndroid Build Coastguard Worker             ae_encrypt(&ctx,NULL,pt+first,second,pt,0,ct+first,NULL,AE_PENDING);
1451*789431f2SAndroid Build Coastguard Worker             ae_encrypt(&ctx,NULL,pt+first+second,third,pt,0,ct+first+second,NULL,AE_FINALIZE);
1452*789431f2SAndroid Build Coastguard Worker             memcpy(next,ct,(size_t)i+OCB_TAG_LEN);
1453*789431f2SAndroid Build Coastguard Worker             next = next+i+OCB_TAG_LEN;
1454*789431f2SAndroid Build Coastguard Worker 
1455*789431f2SAndroid Build Coastguard Worker             ae_encrypt(&ctx,nonce,pt,0,pt,first,ct,NULL,AE_PENDING);
1456*789431f2SAndroid Build Coastguard Worker             ae_encrypt(&ctx,NULL,pt,0,pt+first,second,ct,NULL,AE_PENDING);
1457*789431f2SAndroid Build Coastguard Worker             ae_encrypt(&ctx,NULL,pt,0,pt+first+second,third,ct,NULL,AE_FINALIZE);
1458*789431f2SAndroid Build Coastguard Worker             memcpy(next,ct,OCB_TAG_LEN);
1459*789431f2SAndroid Build Coastguard Worker             next = next+OCB_TAG_LEN;
1460*789431f2SAndroid Build Coastguard Worker         }
1461*789431f2SAndroid Build Coastguard Worker 
1462*789431f2SAndroid Build Coastguard Worker     }
1463*789431f2SAndroid Build Coastguard Worker     nonce[11] = 0;
1464*789431f2SAndroid Build Coastguard Worker     ae_encrypt(&ctx,nonce,NULL,0,val_buf,next-val_buf,ct,tag,AE_FINALIZE);
1465*789431f2SAndroid Build Coastguard Worker     pbuf(tag,OCB_TAG_LEN,0);
1466*789431f2SAndroid Build Coastguard Worker 
1467*789431f2SAndroid Build Coastguard Worker 
1468*789431f2SAndroid Build Coastguard Worker     /* Encrypt/Decrypt test */
1469*789431f2SAndroid Build Coastguard Worker     for (i = 0; i < 128; i++) {
1470*789431f2SAndroid Build Coastguard Worker         int first = ((i/3)/(BPI*16))*(BPI*16);
1471*789431f2SAndroid Build Coastguard Worker         int second = first;
1472*789431f2SAndroid Build Coastguard Worker         int third = i - (first + second);
1473*789431f2SAndroid Build Coastguard Worker 
1474*789431f2SAndroid Build Coastguard Worker         nonce[11] = i%128;
1475*789431f2SAndroid Build Coastguard Worker 
1476*789431f2SAndroid Build Coastguard Worker         if (1) {
1477*789431f2SAndroid Build Coastguard Worker             len = ae_encrypt(&ctx,nonce,val_buf,i,val_buf,i,ct,tag,AE_FINALIZE);
1478*789431f2SAndroid Build Coastguard Worker             len = ae_encrypt(&ctx,nonce,val_buf,i,val_buf,-1,ct,tag,AE_FINALIZE);
1479*789431f2SAndroid Build Coastguard Worker             len = ae_decrypt(&ctx,nonce,ct,len,val_buf,-1,pt,tag,AE_FINALIZE);
1480*789431f2SAndroid Build Coastguard Worker             if (len == -1) { printf("Authentication error: %d\n", i); return; }
1481*789431f2SAndroid Build Coastguard Worker             if (len != i) { printf("Length error: %d\n", i); return; }
1482*789431f2SAndroid Build Coastguard Worker             if (memcmp(val_buf,pt,i)) { printf("Decrypt error: %d\n", i); return; }
1483*789431f2SAndroid Build Coastguard Worker         } else {
1484*789431f2SAndroid Build Coastguard Worker             len = ae_encrypt(&ctx,nonce,val_buf,i,val_buf,i,ct,NULL,AE_FINALIZE);
1485*789431f2SAndroid Build Coastguard Worker             ae_decrypt(&ctx,nonce,ct,first,val_buf,first,pt,NULL,AE_PENDING);
1486*789431f2SAndroid Build Coastguard Worker             ae_decrypt(&ctx,NULL,ct+first,second,val_buf+first,second,pt+first,NULL,AE_PENDING);
1487*789431f2SAndroid Build Coastguard Worker             len = ae_decrypt(&ctx,NULL,ct+first+second,len-(first+second),val_buf+first+second,third,pt+first+second,NULL,AE_FINALIZE);
1488*789431f2SAndroid Build Coastguard Worker             if (len == -1) { printf("Authentication error: %d\n", i); return; }
1489*789431f2SAndroid Build Coastguard Worker             if (memcmp(val_buf,pt,i)) { printf("Decrypt error: %d\n", i); return; }
1490*789431f2SAndroid Build Coastguard Worker         }
1491*789431f2SAndroid Build Coastguard Worker 
1492*789431f2SAndroid Build Coastguard Worker     }
1493*789431f2SAndroid Build Coastguard Worker     printf("Decrypt: PASS\n");
1494*789431f2SAndroid Build Coastguard Worker }
1495*789431f2SAndroid Build Coastguard Worker 
1496*789431f2SAndroid Build Coastguard Worker int main()
1497*789431f2SAndroid Build Coastguard Worker {
1498*789431f2SAndroid Build Coastguard Worker     validate();
1499*789431f2SAndroid Build Coastguard Worker     return 0;
1500*789431f2SAndroid Build Coastguard Worker }
1501*789431f2SAndroid Build Coastguard Worker #endif
1502*789431f2SAndroid Build Coastguard Worker 
1503*789431f2SAndroid Build Coastguard Worker #if USE_AES_NI
1504*789431f2SAndroid Build Coastguard Worker char infoString[] = "OCB3 (AES-NI)";
1505*789431f2SAndroid Build Coastguard Worker #elif USE_REFERENCE_AES
1506*789431f2SAndroid Build Coastguard Worker char infoString[] = "OCB3 (Reference)";
1507*789431f2SAndroid Build Coastguard Worker #elif USE_OPENSSL_AES
1508*789431f2SAndroid Build Coastguard Worker char infoString[] = "OCB3 (OpenSSL)";
1509*789431f2SAndroid Build Coastguard Worker #endif
1510