chiark / gitweb /
rijndael: Make implementation big-endian.
[catacomb] / rijndael-base.c
1 /* -*-c-*-
2  *
3  * $Id: rijndael-base.c,v 1.2 2004/04/08 01:36:15 mdw Exp $
4  *
5  * Low-level stuff for all Rijndael block sizes
6  *
7  * (c) 2001 Straylight/Edgeware
8  */
9
10 /*----- Licensing notice --------------------------------------------------* 
11  *
12  * This file is part of Catacomb.
13  *
14  * Catacomb is free software; you can redistribute it and/or modify
15  * it under the terms of the GNU Library General Public License as
16  * published by the Free Software Foundation; either version 2 of the
17  * License, or (at your option) any later version.
18  * 
19  * Catacomb is distributed in the hope that it will be useful,
20  * but WITHOUT ANY WARRANTY; without even the implied warranty of
21  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22  * GNU Library General Public License for more details.
23  * 
24  * You should have received a copy of the GNU Library General Public
25  * License along with Catacomb; if not, write to the Free
26  * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
27  * MA 02111-1307, USA.
28  */
29
30 /*----- Header files ------------------------------------------------------*/
31
32 #include <assert.h>
33 #include <stdio.h>
34
35 #include <mLib/bits.h>
36
37 #include "blkc.h"
38 #include "gcipher.h"
39 #include "rijndael.h"
40 #include "rijndael-base.h"
41 #include "rijndael-tab.h"
42
43 /*----- Global variables --------------------------------------------------*/
44
45 const octet rijndael_keysz[] = { KSZ_RANGE, RIJNDAEL_KEYSZ, 4, 32, 4 };
46
47 /*----- Constant tables ---------------------------------------------------*/
48
49 const octet rijndael_s[256] = RIJNDAEL_S;
50 const octet rijndael_si[256] = RIJNDAEL_SI;
51 const uint32 rijndael_t[4][256] = RIJNDAEL_T;
52 const uint32 rijndael_ti[4][256] = RIJNDAEL_TI;
53 const uint32 rijndael_u[4][256] = RIJNDAEL_U;
54 const octet rijndael_rcon[] = RIJNDAEL_RCON;
55
56 /*----- Main code ---------------------------------------------------------*/
57
58 /* --- @rijndael_setup@ --- *
59  *
60  * Arguments:   @rijndael_ctx *k@ = pointer to context to initialize
61  *              @unsigned nb@ = number of words in the block
62  *              @const void *buf@ = pointer to buffer of key material
63  *              @size_t sz@ = size of the key material
64  *
65  * Returns:     ---
66  *
67  * Use:         Low-level key-scheduling.
68  */
69
70 void rijndael_setup(rijndael_ctx *k, unsigned nb, const void *buf, size_t sz)
71 {
72   unsigned nk, nr, nw;
73   unsigned i, j, jj;
74   const octet *p;
75   uint32 ww;
76
77   /* --- Sort out the key size --- */
78
79   KSZ_ASSERT(rijndael, sz);
80   nk = sz / 4;
81
82   /* --- Select the number of rounds --- */
83
84   nr = (nk > nb ? nk : nb) + 6;
85   if (nr < 10)
86     nr = 10;
87   k->nr = nr;
88
89   /* --- Fetch the first key words out --- */
90
91   p = buf;
92   for (i = 0; i < nk; i++) {
93     k->w[i] = LOAD32_B(p);
94     p += 4;
95   }
96
97   /* --- Expand this material to fill the rest of the table --- */
98
99   nw = (nr + 1) * nb;
100   ww = k->w[i - 1];
101   p = RCON;
102   for (; i < nw; i++) {
103     uint32 w = k->w[i - nk];
104     if (i % nk == 0) {
105       ww = ROL32(ww, 8);
106       w ^= SUB(S, ww, ww, ww, ww) ^ (*p++ << 24);
107     } else if (nk > 6 && i % nk == 4)
108       w ^= SUB(S, ww, ww, ww, ww);
109     else
110       w ^= ww;
111     k->w[i] = ww = w;
112   }
113
114   /* --- Make the decryption keys --- */
115
116   j = nw; i = 0;
117
118   j -= nb; jj = 0;
119   for (; i < nb; i++)
120     k->wi[i] = k->w[j + jj++];
121
122   for (; i < nw - nb; i += nb) {
123     j -= nb;
124     for (jj = 0; jj < nb; jj++) {
125       uint32 w = k->w[j + jj];
126       k->wi[i + jj] = MIX(U, w, w, w, w);
127     }
128   }
129
130   j -= nb; jj = 0;
131   for (; i < nw; i++)
132     k->wi[i] = k->w[j + jj++];
133 }
134
135 /*----- That's all, folks -------------------------------------------------*/