~ubuntu-branches/ubuntu/quantal/nettle/quantal

« back to all changes in this revision

Viewing changes to aes.c

  • Committer: Bazaar Package Importer
  • Author(s): Marek Habersack
  • Date: 2004-05-04 15:56:02 UTC
  • Revision ID: james.westby@ubuntu.com-20040504155602-7jbhw5mabvwksl3j
Tags: upstream-1.10
Import upstream version 1.10

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* aes.c
 
2
 *
 
3
 * The aes/rijndael block cipher.
 
4
 */
 
5
 
 
6
/* nettle, low-level cryptographics library
 
7
 *
 
8
 * Copyright (C) 2000, 2001 Rafael R. Sevilla, Niels M�ller
 
9
 *  
 
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.
 
14
 * 
 
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.
 
19
 * 
 
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., 59 Temple Place - Suite 330, Boston,
 
23
 * MA 02111-1307, USA.
 
24
 */
 
25
 
 
26
/* Originally written by Rafael R. Sevilla <dido@pacific.net.ph> */
 
27
 
 
28
#if HAVE_CONFIG_H
 
29
# include "config.h"
 
30
#endif
 
31
 
 
32
#include <assert.h>
 
33
 
 
34
#include "aes-internal.h"
 
35
 
 
36
#include "macros.h"
 
37
 
 
38
#ifndef AES_DEBUG
 
39
# define AES_DEBUG 0
 
40
#endif
 
41
 
 
42
#if AES_DEBUG
 
43
# include <stdio.h>
 
44
 
 
45
static void
 
46
d4(const char *name, unsigned r, const uint32_t *data)
 
47
{
 
48
  unsigned j;
 
49
  
 
50
  fprintf(stderr, "aes, %d, %s: ", r, name);
 
51
 
 
52
  for (j = 0; j<4; j++)
 
53
    fprintf(stderr, "%08x, ", data[j]);
 
54
  fprintf(stderr, "\n");
 
55
}
 
56
static void
 
57
d2(const char *aname, uint32_t a, const char *bname,  uint32_t b)
 
58
{
 
59
  fprintf(stderr, "aes, %s: %08x, %s, %08x\n",
 
60
          aname, a, bname, b);
 
61
}
 
62
# define D4(x) d4 x
 
63
# define D2(x) d2 x
 
64
#else
 
65
# define D4(x)
 
66
# define D2(x)
 
67
#endif
 
68
 
 
69
/* Get the byte with index 0, 1, 2 and 3 */
 
70
#define B0(x) ((x) & 0xff)
 
71
#define B1(x) (((x) >> 8) & 0xff)
 
72
#define B2(x) (((x) >> 16) & 0xff)
 
73
#define B3(x) (((x) >> 24) & 0xff)
 
74
 
 
75
#define IDX0(j) (j)
 
76
#define IDX1(j) (T->idx[0][j])
 
77
#define IDX2(j) (T->idx[1][j])
 
78
#define IDX3(j) (T->idx[2][j])
 
79
 
 
80
void
 
81
_aes_crypt(const struct aes_ctx *ctx,
 
82
           const struct aes_table *T,
 
83
           unsigned length, uint8_t *dst,
 
84
           const uint8_t *src)
 
85
{
 
86
  FOR_BLOCKS(length, dst, src, AES_BLOCK_SIZE)
 
87
    {
 
88
      uint32_t wtxt[4];         /* working ciphertext */
 
89
      unsigned i;
 
90
      unsigned round;
 
91
      
 
92
      /* Get clear text, using little-endian byte order.
 
93
       * Also XOR with the first subkey. */
 
94
      for (i = 0; i<4; i++)
 
95
        wtxt[i] = LE_READ_UINT32(src + 4*i) ^ ctx->keys[i];
 
96
 
 
97
      for (round = 1; round < ctx->nrounds; round++)
 
98
        {
 
99
          uint32_t t[4];
 
100
          unsigned j;
 
101
 
 
102
          D4(("wtxt", round, wtxt));
 
103
          D4(("key", round, &ctx->keys[4*round]));
 
104
 
 
105
          /* What's the best way to order this loop? Ideally,
 
106
           * we'd want to keep both t and wtxt in registers. */
 
107
 
 
108
          for (j=0; j<4; j++)
 
109
            {
 
110
              /* FIXME: Figure out how the indexing should really be
 
111
               * done. With the current idx arrays, it looks like the
 
112
               * code shifts the rows in the wrong direction. But it
 
113
               * passes the testsuite. Perhaps the tables are rotated
 
114
               * in the wrong direction, but I don't think so. */
 
115
 
 
116
#if AES_SMALL
 
117
              t[j] =         T->table[0][ B0(wtxt[IDX0(j)]) ] ^
 
118
                ROTRBYTE(    T->table[0][ B1(wtxt[IDX1(j)]) ]^
 
119
                  ROTRBYTE(  T->table[0][ B2(wtxt[IDX2(j)]) ] ^
 
120
                    ROTRBYTE(T->table[0][ B3(wtxt[IDX3(j)]) ])));
 
121
#else /* !AES_SMALL */
 
122
              t[j] = (  T->table[0][ B0(wtxt[IDX0(j)]) ]
 
123
                      ^ T->table[1][ B1(wtxt[IDX1(j)]) ]
 
124
                      ^ T->table[2][ B2(wtxt[IDX2(j)]) ]
 
125
                      ^ T->table[3][ B3(wtxt[IDX3(j)]) ]);
 
126
#endif /* !AES_SMALL */
 
127
            }
 
128
          D4(("t", round, t));
 
129
 
 
130
          for (j = 0; j<4; j++)
 
131
            wtxt[j] = t[j] ^ ctx->keys[4*round + j];
 
132
        }
 
133
      /* Final round */
 
134
      {
 
135
        uint32_t out;
 
136
        unsigned j;
 
137
        for (j = 0; j<4; j++)
 
138
          {
 
139
            /* FIXME: Figure out how the indexing should really be done.
 
140
             * It looks like this code shifts the rows in the wrong
 
141
             * direction, but it passes the testsuite. */
 
142
 
 
143
            out = (   (uint32_t) T->sbox[ B0(wtxt[IDX0(j)]) ]
 
144
                   | ((uint32_t) T->sbox[ B1(wtxt[IDX1(j)]) ] << 8)
 
145
                   | ((uint32_t) T->sbox[ B2(wtxt[IDX2(j)]) ] << 16)
 
146
                   | ((uint32_t) T->sbox[ B3(wtxt[IDX3(j)]) ] << 24));
 
147
 
 
148
            D2(("t", out, "key", ctx->keys[4*round + j]));
 
149
 
 
150
            out ^= ctx->keys[4*round + j];
 
151
 
 
152
            LE_WRITE_UINT32(dst + 4*j, out);
 
153
          }
 
154
      }
 
155
    }
 
156
}