1*8617a60dSAndroid Build Coastguard Worker /* Copyright 2021 The ChromiumOS Authors
2*8617a60dSAndroid Build Coastguard Worker * Use of this source code is governed by a BSD-style license that can be
3*8617a60dSAndroid Build Coastguard Worker * found in the LICENSE file.
4*8617a60dSAndroid Build Coastguard Worker *
5*8617a60dSAndroid Build Coastguard Worker * SHA256 implementation using x86 SHA extension.
6*8617a60dSAndroid Build Coastguard Worker * Mainly from https://github.com/noloader/SHA-Intrinsics/blob/master/sha256-x86.c,
7*8617a60dSAndroid Build Coastguard Worker * Written and place in public domain by Jeffrey Walton
8*8617a60dSAndroid Build Coastguard Worker * Based on code from Intel, and by Sean Gulley for
9*8617a60dSAndroid Build Coastguard Worker * the miTLS project.
10*8617a60dSAndroid Build Coastguard Worker */
11*8617a60dSAndroid Build Coastguard Worker #include "2common.h"
12*8617a60dSAndroid Build Coastguard Worker #include "2sha.h"
13*8617a60dSAndroid Build Coastguard Worker #include "2sha_private.h"
14*8617a60dSAndroid Build Coastguard Worker #include "2api.h"
15*8617a60dSAndroid Build Coastguard Worker
16*8617a60dSAndroid Build Coastguard Worker const uint32_t vb2_hash_seq[8] = {3, 2, 7, 6, 1, 0, 5, 4};
17*8617a60dSAndroid Build Coastguard Worker
18*8617a60dSAndroid Build Coastguard Worker typedef int vb2_m128i __attribute__ ((vector_size(16)));
19*8617a60dSAndroid Build Coastguard Worker
vb2_loadu_si128(vb2_m128i * ptr)20*8617a60dSAndroid Build Coastguard Worker static inline vb2_m128i vb2_loadu_si128(vb2_m128i *ptr)
21*8617a60dSAndroid Build Coastguard Worker {
22*8617a60dSAndroid Build Coastguard Worker vb2_m128i result;
23*8617a60dSAndroid Build Coastguard Worker asm volatile ("movups %1, %0" : "=x"(result) : "m"(*ptr));
24*8617a60dSAndroid Build Coastguard Worker return result;
25*8617a60dSAndroid Build Coastguard Worker }
26*8617a60dSAndroid Build Coastguard Worker
vb2_storeu_si128(vb2_m128i * to,vb2_m128i from)27*8617a60dSAndroid Build Coastguard Worker static inline void vb2_storeu_si128(vb2_m128i *to, vb2_m128i from)
28*8617a60dSAndroid Build Coastguard Worker {
29*8617a60dSAndroid Build Coastguard Worker asm volatile ("movups %1, %0" : "=m"(*to) : "x"(from));
30*8617a60dSAndroid Build Coastguard Worker }
31*8617a60dSAndroid Build Coastguard Worker
vb2_add_epi32(vb2_m128i a,vb2_m128i b)32*8617a60dSAndroid Build Coastguard Worker static inline vb2_m128i vb2_add_epi32(vb2_m128i a, vb2_m128i b)
33*8617a60dSAndroid Build Coastguard Worker {
34*8617a60dSAndroid Build Coastguard Worker return a + b;
35*8617a60dSAndroid Build Coastguard Worker }
36*8617a60dSAndroid Build Coastguard Worker
vb2_shuffle_epi8(vb2_m128i value,vb2_m128i mask)37*8617a60dSAndroid Build Coastguard Worker static inline vb2_m128i vb2_shuffle_epi8(vb2_m128i value, vb2_m128i mask)
38*8617a60dSAndroid Build Coastguard Worker {
39*8617a60dSAndroid Build Coastguard Worker asm ("pshufb %1, %0" : "+x"(value) : "xm"(mask));
40*8617a60dSAndroid Build Coastguard Worker return value;
41*8617a60dSAndroid Build Coastguard Worker }
42*8617a60dSAndroid Build Coastguard Worker
vb2_shuffle_epi32(vb2_m128i value,int mask)43*8617a60dSAndroid Build Coastguard Worker static inline vb2_m128i vb2_shuffle_epi32(vb2_m128i value, int mask)
44*8617a60dSAndroid Build Coastguard Worker {
45*8617a60dSAndroid Build Coastguard Worker vb2_m128i result;
46*8617a60dSAndroid Build Coastguard Worker asm ("pshufd %2, %1, %0" : "=x"(result) : "xm"(value), "i" (mask));
47*8617a60dSAndroid Build Coastguard Worker return result;
48*8617a60dSAndroid Build Coastguard Worker }
49*8617a60dSAndroid Build Coastguard Worker
vb2_alignr_epi8(vb2_m128i a,vb2_m128i b,int imm8)50*8617a60dSAndroid Build Coastguard Worker static inline vb2_m128i vb2_alignr_epi8(vb2_m128i a, vb2_m128i b, int imm8)
51*8617a60dSAndroid Build Coastguard Worker {
52*8617a60dSAndroid Build Coastguard Worker asm ("palignr %2, %1, %0" : "+x"(a) : "xm"(b), "i"(imm8));
53*8617a60dSAndroid Build Coastguard Worker return a;
54*8617a60dSAndroid Build Coastguard Worker }
55*8617a60dSAndroid Build Coastguard Worker
vb2_sha256msg1_epu32(vb2_m128i a,vb2_m128i b)56*8617a60dSAndroid Build Coastguard Worker static inline vb2_m128i vb2_sha256msg1_epu32(vb2_m128i a, vb2_m128i b)
57*8617a60dSAndroid Build Coastguard Worker {
58*8617a60dSAndroid Build Coastguard Worker asm ("sha256msg1 %1, %0" : "+x"(a) : "xm"(b));
59*8617a60dSAndroid Build Coastguard Worker return a;
60*8617a60dSAndroid Build Coastguard Worker }
61*8617a60dSAndroid Build Coastguard Worker
vb2_sha256msg2_epu32(vb2_m128i a,vb2_m128i b)62*8617a60dSAndroid Build Coastguard Worker static inline vb2_m128i vb2_sha256msg2_epu32(vb2_m128i a, vb2_m128i b)
63*8617a60dSAndroid Build Coastguard Worker {
64*8617a60dSAndroid Build Coastguard Worker asm ("sha256msg2 %1, %0" : "+x"(a) : "xm"(b));
65*8617a60dSAndroid Build Coastguard Worker return a;
66*8617a60dSAndroid Build Coastguard Worker }
67*8617a60dSAndroid Build Coastguard Worker
vb2_sha256rnds2_epu32(vb2_m128i a,vb2_m128i b,vb2_m128i k)68*8617a60dSAndroid Build Coastguard Worker static inline vb2_m128i vb2_sha256rnds2_epu32(vb2_m128i a, vb2_m128i b,
69*8617a60dSAndroid Build Coastguard Worker vb2_m128i k)
70*8617a60dSAndroid Build Coastguard Worker {
71*8617a60dSAndroid Build Coastguard Worker asm ("sha256rnds2 %1, %0" : "+x"(a) : "xm"(b), "Yz"(k));
72*8617a60dSAndroid Build Coastguard Worker return a;
73*8617a60dSAndroid Build Coastguard Worker }
74*8617a60dSAndroid Build Coastguard Worker
75*8617a60dSAndroid Build Coastguard Worker #define SHA256_X86_PUT_STATE1(j, i) \
76*8617a60dSAndroid Build Coastguard Worker { \
77*8617a60dSAndroid Build Coastguard Worker msgtmp[j] = vb2_loadu_si128((vb2_m128i *) \
78*8617a60dSAndroid Build Coastguard Worker (message + (i << 6) + (j * 16))); \
79*8617a60dSAndroid Build Coastguard Worker msgtmp[j] = vb2_shuffle_epi8(msgtmp[j], shuf_mask); \
80*8617a60dSAndroid Build Coastguard Worker msg = vb2_add_epi32(msgtmp[j], \
81*8617a60dSAndroid Build Coastguard Worker vb2_loadu_si128((vb2_m128i *)&vb2_sha256_k[j * 4])); \
82*8617a60dSAndroid Build Coastguard Worker state1 = vb2_sha256rnds2_epu32(state1, state0, msg); \
83*8617a60dSAndroid Build Coastguard Worker }
84*8617a60dSAndroid Build Coastguard Worker
85*8617a60dSAndroid Build Coastguard Worker #define SHA256_X86_PUT_STATE0() \
86*8617a60dSAndroid Build Coastguard Worker { \
87*8617a60dSAndroid Build Coastguard Worker msg = vb2_shuffle_epi32(msg, 0x0E); \
88*8617a60dSAndroid Build Coastguard Worker state0 = vb2_sha256rnds2_epu32(state0, state1, msg); \
89*8617a60dSAndroid Build Coastguard Worker }
90*8617a60dSAndroid Build Coastguard Worker
91*8617a60dSAndroid Build Coastguard Worker #define SHA256_X86_LOOP(j) \
92*8617a60dSAndroid Build Coastguard Worker { \
93*8617a60dSAndroid Build Coastguard Worker int k = j & 3; \
94*8617a60dSAndroid Build Coastguard Worker int prev_k = (k + 3) & 3; \
95*8617a60dSAndroid Build Coastguard Worker int next_k = (k + 1) & 3; \
96*8617a60dSAndroid Build Coastguard Worker msg = vb2_add_epi32(msgtmp[k], \
97*8617a60dSAndroid Build Coastguard Worker vb2_loadu_si128((vb2_m128i *)&vb2_sha256_k[j * 4])); \
98*8617a60dSAndroid Build Coastguard Worker state1 = vb2_sha256rnds2_epu32(state1, state0, msg); \
99*8617a60dSAndroid Build Coastguard Worker tmp = vb2_alignr_epi8(msgtmp[k], msgtmp[prev_k], 4); \
100*8617a60dSAndroid Build Coastguard Worker msgtmp[next_k] = vb2_add_epi32(msgtmp[next_k], tmp); \
101*8617a60dSAndroid Build Coastguard Worker msgtmp[next_k] = vb2_sha256msg2_epu32(msgtmp[next_k], \
102*8617a60dSAndroid Build Coastguard Worker msgtmp[k]); \
103*8617a60dSAndroid Build Coastguard Worker SHA256_X86_PUT_STATE0(); \
104*8617a60dSAndroid Build Coastguard Worker msgtmp[prev_k] = vb2_sha256msg1_epu32(msgtmp[prev_k], \
105*8617a60dSAndroid Build Coastguard Worker msgtmp[k]); \
106*8617a60dSAndroid Build Coastguard Worker }
107*8617a60dSAndroid Build Coastguard Worker
vb2_sha256_transform_x86ext(const uint8_t * message,unsigned int block_nb)108*8617a60dSAndroid Build Coastguard Worker static void vb2_sha256_transform_x86ext(const uint8_t *message,
109*8617a60dSAndroid Build Coastguard Worker unsigned int block_nb)
110*8617a60dSAndroid Build Coastguard Worker {
111*8617a60dSAndroid Build Coastguard Worker vb2_m128i state0, state1, msg, abef_save, cdgh_save;
112*8617a60dSAndroid Build Coastguard Worker vb2_m128i msgtmp[4];
113*8617a60dSAndroid Build Coastguard Worker vb2_m128i tmp;
114*8617a60dSAndroid Build Coastguard Worker int i;
115*8617a60dSAndroid Build Coastguard Worker const vb2_m128i shuf_mask = {0x00010203, 0x04050607, 0x08090a0b, 0x0c0d0e0f};
116*8617a60dSAndroid Build Coastguard Worker
117*8617a60dSAndroid Build Coastguard Worker state0 = vb2_loadu_si128((vb2_m128i *)&vb2_sha_ctx.h[0]);
118*8617a60dSAndroid Build Coastguard Worker state1 = vb2_loadu_si128((vb2_m128i *)&vb2_sha_ctx.h[4]);
119*8617a60dSAndroid Build Coastguard Worker for (i = 0; i < (int) block_nb; i++) {
120*8617a60dSAndroid Build Coastguard Worker abef_save = state0;
121*8617a60dSAndroid Build Coastguard Worker cdgh_save = state1;
122*8617a60dSAndroid Build Coastguard Worker
123*8617a60dSAndroid Build Coastguard Worker SHA256_X86_PUT_STATE1(0, i);
124*8617a60dSAndroid Build Coastguard Worker SHA256_X86_PUT_STATE0();
125*8617a60dSAndroid Build Coastguard Worker
126*8617a60dSAndroid Build Coastguard Worker SHA256_X86_PUT_STATE1(1, i);
127*8617a60dSAndroid Build Coastguard Worker SHA256_X86_PUT_STATE0();
128*8617a60dSAndroid Build Coastguard Worker msgtmp[0] = vb2_sha256msg1_epu32(msgtmp[0], msgtmp[1]);
129*8617a60dSAndroid Build Coastguard Worker
130*8617a60dSAndroid Build Coastguard Worker SHA256_X86_PUT_STATE1(2, i);
131*8617a60dSAndroid Build Coastguard Worker SHA256_X86_PUT_STATE0();
132*8617a60dSAndroid Build Coastguard Worker msgtmp[1] = vb2_sha256msg1_epu32(msgtmp[1], msgtmp[2]);
133*8617a60dSAndroid Build Coastguard Worker
134*8617a60dSAndroid Build Coastguard Worker SHA256_X86_PUT_STATE1(3, i);
135*8617a60dSAndroid Build Coastguard Worker tmp = vb2_alignr_epi8(msgtmp[3], msgtmp[2], 4);
136*8617a60dSAndroid Build Coastguard Worker msgtmp[0] = vb2_add_epi32(msgtmp[0], tmp);
137*8617a60dSAndroid Build Coastguard Worker msgtmp[0] = vb2_sha256msg2_epu32(msgtmp[0], msgtmp[3]);
138*8617a60dSAndroid Build Coastguard Worker SHA256_X86_PUT_STATE0();
139*8617a60dSAndroid Build Coastguard Worker msgtmp[2] = vb2_sha256msg1_epu32(msgtmp[2], msgtmp[3]);
140*8617a60dSAndroid Build Coastguard Worker
141*8617a60dSAndroid Build Coastguard Worker SHA256_X86_LOOP(4);
142*8617a60dSAndroid Build Coastguard Worker SHA256_X86_LOOP(5);
143*8617a60dSAndroid Build Coastguard Worker SHA256_X86_LOOP(6);
144*8617a60dSAndroid Build Coastguard Worker SHA256_X86_LOOP(7);
145*8617a60dSAndroid Build Coastguard Worker SHA256_X86_LOOP(8);
146*8617a60dSAndroid Build Coastguard Worker SHA256_X86_LOOP(9);
147*8617a60dSAndroid Build Coastguard Worker SHA256_X86_LOOP(10);
148*8617a60dSAndroid Build Coastguard Worker SHA256_X86_LOOP(11);
149*8617a60dSAndroid Build Coastguard Worker SHA256_X86_LOOP(12);
150*8617a60dSAndroid Build Coastguard Worker SHA256_X86_LOOP(13);
151*8617a60dSAndroid Build Coastguard Worker SHA256_X86_LOOP(14);
152*8617a60dSAndroid Build Coastguard Worker
153*8617a60dSAndroid Build Coastguard Worker msg = vb2_add_epi32(msgtmp[3],
154*8617a60dSAndroid Build Coastguard Worker vb2_loadu_si128((vb2_m128i *)&vb2_sha256_k[15 * 4]));
155*8617a60dSAndroid Build Coastguard Worker state1 = vb2_sha256rnds2_epu32(state1, state0, msg);
156*8617a60dSAndroid Build Coastguard Worker SHA256_X86_PUT_STATE0();
157*8617a60dSAndroid Build Coastguard Worker
158*8617a60dSAndroid Build Coastguard Worker state0 = vb2_add_epi32(state0, abef_save);
159*8617a60dSAndroid Build Coastguard Worker state1 = vb2_add_epi32(state1, cdgh_save);
160*8617a60dSAndroid Build Coastguard Worker
161*8617a60dSAndroid Build Coastguard Worker }
162*8617a60dSAndroid Build Coastguard Worker
163*8617a60dSAndroid Build Coastguard Worker vb2_storeu_si128((vb2_m128i *)&vb2_sha_ctx.h[0], state0);
164*8617a60dSAndroid Build Coastguard Worker vb2_storeu_si128((vb2_m128i *)&vb2_sha_ctx.h[4], state1);
165*8617a60dSAndroid Build Coastguard Worker }
166*8617a60dSAndroid Build Coastguard Worker
vb2_sha256_transform_hwcrypto(const uint8_t * message,unsigned int block_nb)167*8617a60dSAndroid Build Coastguard Worker void vb2_sha256_transform_hwcrypto(const uint8_t *message,
168*8617a60dSAndroid Build Coastguard Worker unsigned int block_nb)
169*8617a60dSAndroid Build Coastguard Worker {
170*8617a60dSAndroid Build Coastguard Worker vb2_sha256_transform_x86ext(message, block_nb);
171*8617a60dSAndroid Build Coastguard Worker }
172