1 /*- 2 * Copyright 2013 John-Mark Gurney <jmg@FreeBSD.org> 3 * Copyright 2015 Netflix, Inc. 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25 * SUCH DAMAGE. 26 * 27 * $FreeBSD$ 28 * 29 */ 30 31 #ifndef _AESENCDEC_H_ 32 #define _AESENCDEC_H_ 33 34 #include <crypto/aesni/aesni_os.h> 35 36 #include <wmmintrin.h> 37 38 static inline void 39 aesni_enc8(int rounds, const __m128i *keysched, __m128i a, 40 __m128i b, __m128i c, __m128i d, __m128i e, __m128i f, __m128i g, 41 __m128i h, __m128i out[8]) 42 { 43 int i; 44 45 a ^= keysched[0]; 46 b ^= keysched[0]; 47 c ^= keysched[0]; 48 d ^= keysched[0]; 49 e ^= keysched[0]; 50 f ^= keysched[0]; 51 g ^= keysched[0]; 52 h ^= keysched[0]; 53 54 for (i = 0; i < rounds; i++) { 55 a = _mm_aesenc_si128(a, keysched[i + 1]); 56 b = _mm_aesenc_si128(b, keysched[i + 1]); 57 c = _mm_aesenc_si128(c, keysched[i + 1]); 58 d = _mm_aesenc_si128(d, keysched[i + 1]); 59 e = _mm_aesenc_si128(e, keysched[i + 1]); 60 f = _mm_aesenc_si128(f, keysched[i + 1]); 61 g = _mm_aesenc_si128(g, keysched[i + 1]); 62 h = _mm_aesenc_si128(h, keysched[i + 1]); 63 } 64 65 out[0] = _mm_aesenclast_si128(a, keysched[i + 1]); 66 out[1] = _mm_aesenclast_si128(b, keysched[i + 1]); 67 out[2] = _mm_aesenclast_si128(c, keysched[i + 1]); 68 out[3] = _mm_aesenclast_si128(d, keysched[i + 1]); 69 out[4] = _mm_aesenclast_si128(e, keysched[i + 1]); 70 out[5] = _mm_aesenclast_si128(f, keysched[i + 1]); 71 out[6] = _mm_aesenclast_si128(g, keysched[i + 1]); 72 out[7] = _mm_aesenclast_si128(h, keysched[i + 1]); 73 } 74 75 static inline void 76 aesni_dec8(int rounds, const __m128i *keysched, __m128i a, 77 __m128i b, __m128i c, __m128i d, __m128i e, __m128i f, __m128i g, 78 __m128i h, __m128i out[8]) 79 { 80 int i; 81 82 a ^= keysched[0]; 83 b ^= keysched[0]; 84 c ^= keysched[0]; 85 d ^= keysched[0]; 86 e ^= keysched[0]; 87 f ^= keysched[0]; 88 g ^= keysched[0]; 89 h ^= keysched[0]; 90 91 for (i = 0; i < rounds; i++) { 92 a = _mm_aesdec_si128(a, keysched[i + 1]); 93 b = _mm_aesdec_si128(b, keysched[i + 1]); 94 c = _mm_aesdec_si128(c, keysched[i + 1]); 95 d = _mm_aesdec_si128(d, keysched[i + 1]); 96 e = _mm_aesdec_si128(e, keysched[i + 1]); 97 f = _mm_aesdec_si128(f, keysched[i + 1]); 98 g = _mm_aesdec_si128(g, keysched[i + 1]); 99 h = _mm_aesdec_si128(h, keysched[i + 1]); 100 } 101 102 out[0] = _mm_aesdeclast_si128(a, keysched[i + 1]); 103 out[1] = _mm_aesdeclast_si128(b, keysched[i + 1]); 104 out[2] = _mm_aesdeclast_si128(c, keysched[i + 1]); 105 out[3] = _mm_aesdeclast_si128(d, keysched[i + 1]); 106 out[4] = _mm_aesdeclast_si128(e, keysched[i + 1]); 107 out[5] = _mm_aesdeclast_si128(f, keysched[i + 1]); 108 out[6] = _mm_aesdeclast_si128(g, keysched[i + 1]); 109 out[7] = _mm_aesdeclast_si128(h, keysched[i + 1]); 110 } 111 112 /* rounds is passed in as rounds - 1 */ 113 static inline __m128i 114 aesni_enc(int rounds, const __m128i *keysched, const __m128i from) 115 { 116 __m128i tmp; 117 int i; 118 119 tmp = from ^ keysched[0]; 120 for (i = 1; i < rounds; i += 2) { 121 tmp = _mm_aesenc_si128(tmp, keysched[i]); 122 tmp = _mm_aesenc_si128(tmp, keysched[i + 1]); 123 } 124 125 tmp = _mm_aesenc_si128(tmp, keysched[rounds]); 126 return _mm_aesenclast_si128(tmp, keysched[rounds + 1]); 127 } 128 129 static inline __m128i 130 aesni_dec(int rounds, const __m128i *keysched, const __m128i from) 131 { 132 __m128i tmp; 133 int i; 134 135 tmp = from ^ keysched[0]; 136 137 for (i = 1; i < rounds; i += 2) { 138 tmp = _mm_aesdec_si128(tmp, keysched[i]); 139 tmp = _mm_aesdec_si128(tmp, keysched[i + 1]); 140 } 141 142 tmp = _mm_aesdec_si128(tmp, keysched[rounds]); 143 return _mm_aesdeclast_si128(tmp, keysched[rounds + 1]); 144 } 145 146 #endif /* _AESENCDEC_H_ */ 147