1 /* aes-encrypt-internal.c
3 * Encryption function for the aes/rijndael block cipher.
6 /* nettle, low-level cryptographics library
8 * Copyright (C) 2002 Niels Möller
10 * The nettle library is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU Lesser General Public License as published by
12 * the Free Software Foundation; either version 2.1 of the License, or (at your
13 * option) any later version.
15 * The nettle library is distributed in the hope that it will be useful, but
16 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
17 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
18 * License for more details.
20 * You should have received a copy of the GNU Lesser General Public License
21 * along with the nettle library; see the file COPYING.LIB. If not, write to
22 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
32 #include "aes-internal.h"
36 _nettle_aes_encrypt(const struct aes_ctx
*ctx
,
37 const struct aes_table
*T
,
38 unsigned length
, uint8_t *dst
,
41 FOR_BLOCKS(length
, dst
, src
, AES_BLOCK_SIZE
)
43 uint32_t w0
, w1
, w2
, w3
; /* working ciphertext */
44 uint32_t t0
, t1
, t2
, t3
;
47 /* Get clear text, using little-endian byte order.
48 * Also XOR with the first subkey. */
50 w0
= LE_READ_UINT32(src
) ^ ctx
->keys
[0];
51 w1
= LE_READ_UINT32(src
+ 4) ^ ctx
->keys
[1];
52 w2
= LE_READ_UINT32(src
+ 8) ^ ctx
->keys
[2];
53 w3
= LE_READ_UINT32(src
+ 12) ^ ctx
->keys
[3];
55 for (round
= 1; round
< ctx
->nrounds
; round
++)
57 t0
= AES_ROUND(T
, w0
, w1
, w2
, w3
, ctx
->keys
[4*round
]);
58 t1
= AES_ROUND(T
, w1
, w2
, w3
, w0
, ctx
->keys
[4*round
+ 1]);
59 t2
= AES_ROUND(T
, w2
, w3
, w0
, w1
, ctx
->keys
[4*round
+ 2]);
60 t3
= AES_ROUND(T
, w3
, w0
, w1
, w2
, ctx
->keys
[4*round
+ 3]);
62 /* We could unroll the loop twice, to avoid these
63 assignments. If all eight variables fit in registers,
64 that should give a slight speedup. */
73 t0
= AES_FINAL_ROUND(T
, w0
, w1
, w2
, w3
, ctx
->keys
[4*round
]);
74 t1
= AES_FINAL_ROUND(T
, w1
, w2
, w3
, w0
, ctx
->keys
[4*round
+ 1]);
75 t2
= AES_FINAL_ROUND(T
, w2
, w3
, w0
, w1
, ctx
->keys
[4*round
+ 2]);
76 t3
= AES_FINAL_ROUND(T
, w3
, w0
, w1
, w2
, ctx
->keys
[4*round
+ 3]);
78 LE_WRITE_UINT32(dst
, t0
);
79 LE_WRITE_UINT32(dst
+ 8, t2
);
80 LE_WRITE_UINT32(dst
+ 4, t1
);
81 LE_WRITE_UINT32(dst
+ 12, t3
);
85 /* Some stats, all for AES 128:
87 A. Table-driven indexing (the approach of the old unified
89 B. Unrolling the j-loop.
91 C. Eliminated the use of IDXk(j) in the main loop.
93 D. Put wtxt in four scalar variables.
95 E. Also put t in four scalar variables.
97 P4 2.2 GHz AMD Duron 1.4GHz