~ubuntu-branches/ubuntu/gutsy/openafs/gutsy

« back to all changes in this revision

Viewing changes to src/rxkad/domestic/fcrypt.c

  • Committer: Bazaar Package Importer
  • Author(s): Sam Hartman
  • Date: 2004-01-10 16:37:33 UTC
  • Revision ID: james.westby@ubuntu.com-20040110163733-jvr0n1uahshlb1uu
Tags: upstream-1.2.11
ImportĀ upstreamĀ versionĀ 1.2.11

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright 2000, International Business Machines Corporation and others.
 
3
 * All Rights Reserved.
 
4
 * 
 
5
 * This software has been released under the terms of the IBM Public
 
6
 * License.  For details, see the LICENSE file in the top-level source
 
7
 * directory or online at http://www.openafs.org/dl/license10.html
 
8
 */
 
9
 
 
10
/* NOTE: fc_cbc_encrypt now modifies its 5th argument, to permit chaining over
 
11
 * scatter/gather vectors.
 
12
 */
 
13
 
 
14
 
 
15
#include <afsconfig.h>
 
16
#ifdef KERNEL
 
17
#include "../afs/param.h"
 
18
#else
 
19
#include <afs/param.h>
 
20
#endif
 
21
 
 
22
RCSID("$Header: /afs/sipb.mit.edu/project/openafs/debian/cvs/openafs/src/rxkad/domestic/fcrypt.c,v 1.1.1.6 2001/09/11 14:34:46 hartmans Exp $");
 
23
 
 
24
#define DEBUG 0
 
25
#ifdef KERNEL
 
26
#ifndef UKERNEL
 
27
#include "../afs/stds.h"
 
28
#include "../h/types.h"
 
29
#ifndef AFS_LINUX20_ENV
 
30
#include "../netinet/in.h"
 
31
#endif
 
32
#else /* UKERNEL */
 
33
#include "../afs/sysincludes.h"
 
34
#include "../afs/stds.h"
 
35
#endif /* UKERNEL */
 
36
#ifdef AFS_LINUX22_ENV
 
37
#include <asm/byteorder.h>
 
38
#endif
 
39
 
 
40
#include "../afs/longc_procs.h"
 
41
 
 
42
#else /* KERNEL */
 
43
 
 
44
#include <afs/stds.h>
 
45
#include <sys/types.h>
 
46
#ifdef AFS_NT40_ENV
 
47
#include <winsock2.h>
 
48
#else
 
49
#include <netinet/in.h>
 
50
#endif
 
51
#include <rx/rx.h>
 
52
#endif /* KERNEL */
 
53
 
 
54
#include "sboxes.h"
 
55
#include "fcrypt.h"
 
56
#include "rxkad.h"
 
57
 
 
58
 
 
59
#ifdef TCRYPT
 
60
int ROUNDS = 16;
 
61
#else
 
62
#define ROUNDS 16
 
63
#endif
 
64
 
 
65
#define XPRT_FCRYPT
 
66
 
 
67
int fc_keysched (key, schedule)
 
68
  IN struct ktc_encryptionKey *key;
 
69
  OUT fc_KeySchedule    schedule;
 
70
{   unsigned char *keychar = (unsigned char *)key;
 
71
    afs_uint32  kword[2];
 
72
 
 
73
    unsigned int   temp;
 
74
    int            i;
 
75
 
 
76
    /* first, flush the losing key parity bits. */
 
77
    kword[0] = (*keychar++) >> 1;
 
78
    kword[0] <<= 7;
 
79
    kword[0] += (*keychar++) >> 1;
 
80
    kword[0] <<= 7;
 
81
    kword[0] += (*keychar++) >> 1;
 
82
    kword[0] <<= 7;
 
83
    kword[0] += (*keychar++) >> 1;
 
84
    kword[1] = kword[0] >> 4;           /* get top 24 bits for hi word */
 
85
    kword[0] &= 0xf;
 
86
    kword[0] <<= 7;
 
87
    kword[0] += (*keychar++) >> 1;
 
88
    kword[0] <<= 7;
 
89
    kword[0] += (*keychar++) >> 1;
 
90
    kword[0] <<= 7;
 
91
    kword[0] += (*keychar++) >> 1;
 
92
    kword[0] <<= 7;
 
93
    kword[0] += (*keychar) >> 1;
 
94
 
 
95
    schedule[0] = kword[0];
 
96
    for (i=1; i<ROUNDS; i++) {
 
97
        /* rotate right 3 */
 
98
        temp = kword[0] & ((1<<11)-1);  /* get 11 lsb */
 
99
        kword[0] = (kword[0] >> 11) | ((kword[1] & ((1<<11)-1)) << (32-11));
 
100
        kword[1] = (kword[1] >> 11) | (temp << (56-32-11));
 
101
        schedule[i] = kword[0];
 
102
    }
 
103
    LOCK_RXKAD_STATS
 
104
    rxkad_stats.fc_key_scheds++;
 
105
    UNLOCK_RXKAD_STATS
 
106
    return 0;
 
107
}
 
108
 
 
109
afs_int32 fc_ecb_encrypt(clear, cipher, schedule, encrypt)
 
110
  IN afs_uint32  *clear;
 
111
  OUT afs_uint32 *cipher;
 
112
  IN fc_KeySchedule  schedule;
 
113
  IN int             encrypt;   /* 0 ==> decrypt, else encrypt */
 
114
{   afs_uint32  L,R;
 
115
    afs_uint32  S,P;
 
116
    unsigned char *Pchar = (unsigned char *)&P;
 
117
    unsigned char *Schar = (unsigned char *)&S;
 
118
    int i;
 
119
 
 
120
#if defined(vax) || (defined(mips) && defined(MIPSEL)) || defined(AFSLITTLE_ENDIAN)
 
121
#define Byte0 3 
 
122
#define Byte1 2
 
123
#define Byte2 1
 
124
#define Byte3 0
 
125
#else
 
126
#define Byte0 0
 
127
#define Byte1 1
 
128
#define Byte2 2
 
129
#define Byte3 3
 
130
#endif
 
131
 
 
132
#if 0
 
133
    memcpy(&L, clear, sizeof(afs_int32));
 
134
    memcpy(&R, clear+1, sizeof(afs_int32));
 
135
#else
 
136
    L = ntohl(*clear);
 
137
    R = ntohl(*(clear+1));
 
138
#endif
 
139
 
 
140
    if (encrypt) {
 
141
        LOCK_RXKAD_STATS
 
142
        rxkad_stats.fc_encrypts[ENCRYPT]++;
 
143
        UNLOCK_RXKAD_STATS
 
144
        for (i=0; i<(ROUNDS/2); i++) {
 
145
            S = *schedule++ ^ R;        /* xor R with key bits from schedule */
 
146
            Pchar[Byte2] = sbox0[Schar[Byte0]]; /* do 8-bit S Box subst. */
 
147
            Pchar[Byte3] = sbox1[Schar[Byte1]]; /* and permute the result */
 
148
            Pchar[Byte1] = sbox2[Schar[Byte2]];
 
149
            Pchar[Byte0] = sbox3[Schar[Byte3]];
 
150
            P = (P >> 5) | ((P & ((1<<5)-1)) << (32-5)); /* right rot 5 bits */
 
151
            L ^= P;                     /* we're done with L, so save there */
 
152
            S = *schedule++ ^ L;        /* this time xor with L */
 
153
            Pchar[Byte2] = sbox0[Schar[Byte0]];
 
154
            Pchar[Byte3] = sbox1[Schar[Byte1]];
 
155
            Pchar[Byte1] = sbox2[Schar[Byte2]];
 
156
            Pchar[Byte0] = sbox3[Schar[Byte3]];
 
157
            P = (P >> 5) | ((P & ((1<<5)-1)) << (32-5)); /* right rot 5 bits */
 
158
            R ^= P;
 
159
        }
 
160
    }
 
161
    else {
 
162
        LOCK_RXKAD_STATS
 
163
        rxkad_stats.fc_encrypts[DECRYPT]++;
 
164
        UNLOCK_RXKAD_STATS
 
165
        schedule = &schedule[ROUNDS-1]; /* start at end of key schedule */
 
166
        for (i=0; i<(ROUNDS/2); i++) {
 
167
            S = *schedule-- ^ L;        /* xor R with key bits from schedule */
 
168
            Pchar[Byte2] = sbox0[Schar[Byte0]]; /* do 8-bit S Box subst. and */
 
169
            Pchar[Byte3] = sbox1[Schar[Byte1]]; /* permute the result */
 
170
            Pchar[Byte1] = sbox2[Schar[Byte2]];
 
171
            Pchar[Byte0] = sbox3[Schar[Byte3]];
 
172
            P = (P >> 5) | ((P & ((1<<5)-1)) << (32-5)); /* right rot 5 bits */
 
173
            R ^= P;                     /* we're done with L, so save there */
 
174
            S = *schedule-- ^ R;        /* this time xor with L */
 
175
            Pchar[Byte2] = sbox0[Schar[Byte0]];
 
176
            Pchar[Byte3] = sbox1[Schar[Byte1]];
 
177
            Pchar[Byte1] = sbox2[Schar[Byte2]];
 
178
            Pchar[Byte0] = sbox3[Schar[Byte3]];
 
179
            P = (P >> 5) | ((P & ((1<<5)-1)) << (32-5)); /* right rot 5 bits */
 
180
            L ^= P;
 
181
        }
 
182
    }
 
183
#if 0
 
184
    memcpy(cipher, &L, sizeof(afs_int32));
 
185
    memcpy(cipher+1, &R, sizeof(afs_int32));
 
186
#else
 
187
    *cipher = htonl(L);
 
188
    *(cipher+1) = htonl(R);
 
189
#endif
 
190
    return 0;
 
191
}
 
192
 
 
193
/* Crypting can be done in segments by recycling xor.  All but the final segment must
 
194
 * be multiples of 8 bytes.
 
195
 * NOTE: fc_cbc_encrypt now modifies its 5th argument, to permit chaining over
 
196
 * scatter/gather vectors.
 
197
 */
 
198
afs_int32 fc_cbc_encrypt (input, output, length, key, xor, encrypt)
 
199
  char          *input;
 
200
  char          *output;
 
201
  afs_int32              length;                /* in bytes */
 
202
  int            encrypt;               /* 0 ==> decrypt, else encrypt */
 
203
  fc_KeySchedule key;                   /* precomputed key schedule */
 
204
  afs_uint32 *xor;                      /* 8 bytes of initialization vector */
 
205
{   afs_uint32 i,j;
 
206
    afs_uint32 t_input[2];
 
207
    afs_uint32 t_output[2];
 
208
    unsigned char *t_in_p = (unsigned char *) t_input;
 
209
 
 
210
    if (encrypt) {
 
211
        for (i = 0; length > 0; i++, length -= 8) {
 
212
            /* get input */
 
213
            memcpy(t_input, input, sizeof(t_input));
 
214
            input += sizeof(t_input);
 
215
 
 
216
            /* zero pad */
 
217
            for (j = length; j <= 7; j++)
 
218
                *(t_in_p+j)= 0;
 
219
 
 
220
            /* do the xor for cbc into the temp */
 
221
            xor[0] ^= t_input[0] ;
 
222
            xor[1] ^= t_input[1] ;
 
223
            /* encrypt */
 
224
            fc_ecb_encrypt (xor, t_output, key, encrypt);
 
225
 
 
226
            /* copy temp output and save it for cbc */
 
227
            memcpy(output, t_output, sizeof(t_output));
 
228
            output += sizeof(t_output);
 
229
 
 
230
            /* calculate xor value for next round from plain & cipher text */
 
231
            xor[0] = t_input[0] ^ t_output[0];
 
232
            xor[1] = t_input[1] ^ t_output[1];
 
233
 
 
234
 
 
235
        }
 
236
        t_output[0] = 0;
 
237
        t_output[1] = 0;
 
238
    }
 
239
    else {
 
240
        /* decrypt */
 
241
        for (i = 0; length > 0; i++, length -= 8) {
 
242
            /* get input */
 
243
            memcpy(t_input, input, sizeof(t_input));
 
244
            input += sizeof(t_input);
 
245
 
 
246
            /* no padding for decrypt */
 
247
            fc_ecb_encrypt(t_input, t_output, key, encrypt);
 
248
 
 
249
            /* do the xor for cbc into the output */
 
250
            t_output[0] ^= xor[0] ;
 
251
            t_output[1] ^= xor[1] ;
 
252
 
 
253
            /* copy temp output */
 
254
            memcpy(output, t_output, sizeof(t_output));
 
255
            output += sizeof(t_output);
 
256
 
 
257
            /* calculate xor value for next round from plain & cipher text */
 
258
            xor[0] = t_input[0] ^ t_output[0];
 
259
            xor[1] = t_input[1] ^ t_output[1];
 
260
        }
 
261
    }
 
262
    return 0;
 
263
}