libsodium: Needed for Dnscrypto-proxy Release 1.3.0
[tomato.git] / release / src / router / libsodium / src / libsodium / crypto_stream / aes256estream / hongjun / aes256-ctr.c
blob3aa970ecc7139d63c4593186f9b914e916b01d3a
1 /* aes-ctr.c */
2 /* AES in CTR mode. */
4 /* Hongjun Wu, January 2007*/
7 /* ------------------------------------------------------------------------- */
9 #include "api.h"
10 #include "aes256.h"
12 #include <string.h>
14 /* ------------------------------------------------------------------------- */
15 /* key setup for AES-256*/
16 static void
17 ECRYPT_keysetup(ECRYPT_ctx* ctx, const u8* key, u32 keysize, u32 ivsize)
19 unsigned int w[Nk*(Nr+1)], temp;
20 int i, j;
22 (void) keysize;
23 (void) ivsize;
24 (void) sizeof(char[sizeof *ctx == crypto_stream_BEFORENMBYTES ? 1 : -1]);
26 for( i = 0; i < Nk; i++ ) {
27 w[i] = key[(i << 2)];
28 w[i] |= key[(i << 2)+1] << 8;
29 w[i] |= key[(i << 2)+2] << 16;
30 w[i] |= key[(i << 2)+3] << 24;
33 i = Nk;
35 while( i < Nb*(Nr+1) ) {
36 temp = w[i-1];
38 temp = Sbox[ temp & 0xFF] << 24 ^
39 Sbox[(temp >> 8) & 0xFF] ^
40 (Sbox[(temp >> 16) & 0xFF] << 8 ) ^
41 (Sbox[(temp >> 24) & 0xFF] << 16) ^
42 Rcon[i/Nk];
43 w[i] = w[i-Nk] ^ temp;
44 i++;
46 temp = w[i-1];
47 w[i] = w[i-Nk] ^ temp;
48 i++;
50 temp = w[i-1];
51 w[i] = w[i-Nk] ^ temp;
52 i++;
54 temp = w[i-1];
55 w[i] = w[i-Nk] ^ temp;
56 i++;
58 temp = w[i-1];
59 temp = Sbox[ temp & 0xFF] ^
60 Sbox[(temp >> 8) & 0xFF] << 8 ^
61 (Sbox[(temp >> 16) & 0xFF] << 16 ) ^
62 (Sbox[(temp >> 24) & 0xFF] << 24);
63 w[i] = w[i-Nk] ^ temp;
64 i++;
66 temp = w[i-1];
67 w[i] = w[i-Nk] ^ temp;
68 i++;
70 temp = w[i-1];
71 w[i] = w[i-Nk] ^ temp;
72 i++;
74 temp = w[i-1];
75 w[i] = w[i-Nk] ^ temp;
76 i++;
79 for (i = 0; i <= Nr; i++) {
80 for (j = 0; j < Nb; j++) {
81 ctx->round_key[i][j] = w[(i<<2)+j];
86 /* ------------------------------------------------------------------------- */
88 static void
89 ECRYPT_ivsetup(ECRYPT_ctx* ctx, const u8* iv)
91 (void) sizeof(char[(sizeof ctx->counter) == crypto_stream_NONCEBYTES ? 1 : -1]);
92 memcpy(ctx->counter, iv, crypto_stream_NONCEBYTES);
95 /* ------------------------------------------------------------------------- */
97 static void
98 ECRYPT_process_bytes(int action, ECRYPT_ctx* ctx, const u8* input, u8* output,
99 u32 msglen)
101 u8 keystream[16];
102 u32 i;
104 (void) action;
105 memset(keystream, 0, sizeof keystream);
106 partial_precompute_tworounds(ctx);
108 for ( ; msglen >= 16; msglen -= 16, input += 16, output += 16) {
109 aes256_enc_block(ctx->counter, keystream, ctx);
111 ((u32*)output)[0] = ((u32*)input)[0] ^ ((u32*)keystream)[0] ^ ctx->round_key[Nr][0];
112 ((u32*)output)[1] = ((u32*)input)[1] ^ ((u32*)keystream)[1] ^ ctx->round_key[Nr][1];
113 ((u32*)output)[2] = ((u32*)input)[2] ^ ((u32*)keystream)[2] ^ ctx->round_key[Nr][2];
114 ((u32*)output)[3] = ((u32*)input)[3] ^ ((u32*)keystream)[3] ^ ctx->round_key[Nr][3];
116 ctx->counter[0]++;
118 if ((ctx->counter[0] & 0xff)== 0) {
119 partial_precompute_tworounds(ctx);
123 if (msglen > 0) {
124 aes256_enc_block(ctx->counter, keystream, ctx);
125 ((u32*)keystream)[0] ^= ctx->round_key[Nr][0];
126 ((u32*)keystream)[1] ^= ctx->round_key[Nr][1];
127 ((u32*)keystream)[2] ^= ctx->round_key[Nr][2];
128 ((u32*)keystream)[3] ^= ctx->round_key[Nr][3];
130 for (i = 0; i < msglen; i ++) {
131 output[i] = input[i] ^ keystream[i];
136 /* ------------------------------------------------------------------------- */
138 #include "ecrypt-sync.h"
141 crypto_stream_beforenm(unsigned char *c, const unsigned char *k)
143 ECRYPT_ctx * const ctx = (ECRYPT_ctx *) c;
145 ECRYPT_keysetup(ctx, k, crypto_stream_KEYBYTES * 8,
146 crypto_stream_NONCEBYTES * 8);
147 return 0;
151 crypto_stream_afternm(unsigned char *outp, unsigned long long len,
152 const unsigned char *noncep, const unsigned char *c)
154 ECRYPT_ctx * const ctx = (ECRYPT_ctx *) c;
155 unsigned long long i;
157 ECRYPT_ivsetup(ctx, noncep);
158 for (i = 0U; i < len; ++i) {
159 outp[i] = 0U;
161 ECRYPT_encrypt_bytes(ctx, (u8 *) outp, (u8 *) outp, len);
163 return 0;
167 crypto_stream_xor_afternm(unsigned char *outp, const unsigned char *inp,
168 unsigned long long len, const unsigned char *noncep,
169 const unsigned char *c)
171 ECRYPT_ctx * const ctx = (ECRYPT_ctx *) c;
173 ECRYPT_ivsetup(ctx, noncep);
174 ECRYPT_encrypt_bytes(ctx, (const u8 *) inp, (u8 *) outp, len);
176 return 0;
180 crypto_stream(unsigned char *out, unsigned long long outlen,
181 const unsigned char *n, const unsigned char *k)
183 unsigned char d[crypto_stream_BEFORENMBYTES];
184 crypto_stream_beforenm(d, k);
185 crypto_stream_afternm(out, outlen, n, d);
187 return 0;
190 int crypto_stream_xor(unsigned char *out, const unsigned char *in,
191 unsigned long long inlen, const unsigned char *n,
192 const unsigned char *k)
194 unsigned char d[crypto_stream_BEFORENMBYTES];
196 crypto_stream_beforenm(d, k);
197 crypto_stream_xor_afternm(out, in, inlen, n, d);
199 return 0;