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