a5a9a7a96226260cf1e998254c48ffdd6804195b
[trex.git] /
1 /* Author: Peter Schwabe, ported from an assembly implementation by Emilia Käsper
2  * Date: 2009-03-19
3  * Public domain */
4
5 #include "api.h"
6 #include "int128.h"
7 #include "common.h"
8 #include "consts.h"
9
10 int crypto_stream_afternm(unsigned char *out, unsigned long long len, const unsigned char *nonce, const unsigned char *c)
11 {
12
13   int128 xmm0;
14   int128 xmm1;
15   int128 xmm2;
16   int128 xmm3;
17   int128 xmm4;
18   int128 xmm5;
19   int128 xmm6;
20   int128 xmm7;
21
22   int128 xmm8;
23   int128 xmm9;
24   int128 xmm10;
25   int128 xmm11;
26   int128 xmm12;
27   int128 xmm13;
28   int128 xmm14;
29   int128 xmm15;
30
31   int128 nonce_stack;
32   unsigned long long lensav;
33   unsigned char bl[128];
34   unsigned char *blp;
35   unsigned char *np;
36   unsigned char b;
37
38   uint32 tmp;
39
40   /* Copy nonce on the stack */
41   copy2(&nonce_stack, (const int128 *) (nonce + 0));
42   np = (unsigned char *)&nonce_stack;
43
44     enc_block:
45
46     xmm0 = *(int128 *) (np + 0);
47     copy2(&xmm1, &xmm0);
48     shufb(&xmm1, SWAP32);
49     copy2(&xmm2, &xmm1);
50     copy2(&xmm3, &xmm1);
51     copy2(&xmm4, &xmm1);
52     copy2(&xmm5, &xmm1);
53     copy2(&xmm6, &xmm1);
54     copy2(&xmm7, &xmm1);
55
56     add_uint32_big(&xmm1, 1);
57     add_uint32_big(&xmm2, 2);
58     add_uint32_big(&xmm3, 3);
59     add_uint32_big(&xmm4, 4);
60     add_uint32_big(&xmm5, 5);
61     add_uint32_big(&xmm6, 6);
62     add_uint32_big(&xmm7, 7);
63
64     shufb(&xmm0, M0);
65     shufb(&xmm1, M0SWAP);
66     shufb(&xmm2, M0SWAP);
67     shufb(&xmm3, M0SWAP);
68     shufb(&xmm4, M0SWAP);
69     shufb(&xmm5, M0SWAP);
70     shufb(&xmm6, M0SWAP);
71     shufb(&xmm7, M0SWAP);
72
73     bitslice(xmm7, xmm6, xmm5, xmm4, xmm3, xmm2, xmm1, xmm0, xmm8)
74
75     aesround( 1, xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7, xmm8, xmm9, xmm10, xmm11, xmm12, xmm13, xmm14, xmm15,c)
76     aesround( 2, xmm8, xmm9, xmm10, xmm11, xmm12, xmm13, xmm14, xmm15, xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7,c)
77     aesround( 3, xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7, xmm8, xmm9, xmm10, xmm11, xmm12, xmm13, xmm14, xmm15,c)
78     aesround( 4, xmm8, xmm9, xmm10, xmm11, xmm12, xmm13, xmm14, xmm15, xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7,c)
79     aesround( 5, xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7, xmm8, xmm9, xmm10, xmm11, xmm12, xmm13, xmm14, xmm15,c)
80     aesround( 6, xmm8, xmm9, xmm10, xmm11, xmm12, xmm13, xmm14, xmm15, xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7,c)
81     aesround( 7, xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7, xmm8, xmm9, xmm10, xmm11, xmm12, xmm13, xmm14, xmm15,c)
82     aesround( 8, xmm8, xmm9, xmm10, xmm11, xmm12, xmm13, xmm14, xmm15, xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7,c)
83     aesround( 9, xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7, xmm8, xmm9, xmm10, xmm11, xmm12, xmm13, xmm14, xmm15,c)
84     lastround(xmm8, xmm9, xmm10, xmm11, xmm12, xmm13, xmm14, xmm15, xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7,c)
85
86     bitslice(xmm13, xmm10, xmm15, xmm11, xmm14, xmm12, xmm9, xmm8, xmm0)
87
88     if(len < 128) goto partial;
89     if(len == 128) goto full;
90
91     tmp = load32_bigendian(np + 12);
92     tmp += 8;
93     store32_bigendian(np + 12, tmp);
94
95     *(int128 *) (out + 0) = xmm8;
96     *(int128 *) (out + 16) = xmm9;
97     *(int128 *) (out + 32) = xmm12;
98     *(int128 *) (out + 48) = xmm14;
99     *(int128 *) (out + 64) = xmm11;
100     *(int128 *) (out + 80) = xmm15;
101     *(int128 *) (out + 96) = xmm10;
102     *(int128 *) (out + 112) = xmm13;
103
104     len -= 128;
105     out += 128;
106
107     goto enc_block;
108
109     partial:
110
111     lensav = len;
112     len >>= 4;
113
114     tmp = load32_bigendian(np + 12);
115     tmp += len;
116     store32_bigendian(np + 12, tmp);
117
118     blp = bl;
119     *(int128 *)(blp + 0) = xmm8;
120     *(int128 *)(blp + 16) = xmm9;
121     *(int128 *)(blp + 32) = xmm12;
122     *(int128 *)(blp + 48) = xmm14;
123     *(int128 *)(blp + 64) = xmm11;
124     *(int128 *)(blp + 80) = xmm15;
125     *(int128 *)(blp + 96) = xmm10;
126     *(int128 *)(blp + 112) = xmm13;
127
128     bytes:
129
130     if(lensav == 0) goto end;
131
132     b = blp[0]; /* clang false positive */
133     *(unsigned char *)(out + 0) = b;
134
135     blp += 1;
136     out +=1;
137     lensav -= 1;
138
139     goto bytes;
140
141     full:
142
143     tmp = load32_bigendian(np + 12);
144     tmp += 8;
145     store32_bigendian(np + 12, tmp);
146
147     *(int128 *) (out + 0) = xmm8;
148     *(int128 *) (out + 16) = xmm9;
149     *(int128 *) (out + 32) = xmm12;
150     *(int128 *) (out + 48) = xmm14;
151     *(int128 *) (out + 64) = xmm11;
152     *(int128 *) (out + 80) = xmm15;
153     *(int128 *) (out + 96) = xmm10;
154     *(int128 *) (out + 112) = xmm13;
155
156     end:
157     return 0;
158
159 }