~ubuntu-branches/ubuntu/lucid/seamonkey/lucid-security

« back to all changes in this revision

Viewing changes to security/nss-fips/lib/freebl/desblapi.c

  • Committer: Bazaar Package Importer
  • Author(s): Fabien Tassin
  • Date: 2008-07-29 21:29:02 UTC
  • mfrom: (1.1.4 upstream)
  • Revision ID: james.westby@ubuntu.com-20080729212902-spm9kpvchp9udwbw
Tags: 1.1.11+nobinonly-0ubuntu1
* New security upstream release: 1.1.11 (LP: #218534)
  Fixes USN-602-1, USN-619-1, USN-623-1 and USN-629-1
* Refresh diverged patch:
  - update debian/patches/80_security_build.patch
* Fix FTBFS with missing -lfontconfig
  - add debian/patches/11_fix_ftbfs_with_fontconfig.patch
  - update debian/patches/series
* Build with default gcc (hardy: 4.2, intrepid: 4.3)
  - update debian/rules
  - update debian/control

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 *  desblapi.c
 
3
 *
 
4
 *  core source file for DES-150 library
 
5
 *  Implement DES Modes of Operation and Triple-DES.
 
6
 *  Adapt DES-150 to blapi API.
 
7
 *
 
8
 * ***** BEGIN LICENSE BLOCK *****
 
9
 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
 
10
 *
 
11
 * The contents of this file are subject to the Mozilla Public License Version
 
12
 * 1.1 (the "License"); you may not use this file except in compliance with
 
13
 * the License. You may obtain a copy of the License at
 
14
 * http://www.mozilla.org/MPL/
 
15
 *
 
16
 * Software distributed under the License is distributed on an "AS IS" basis,
 
17
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 
18
 * for the specific language governing rights and limitations under the
 
19
 * License.
 
20
 *
 
21
 * The Original Code is the DES-150 library.
 
22
 *
 
23
 * The Initial Developer of the Original Code is
 
24
 * Nelson B. Bolyard, nelsonb@iname.com.
 
25
 * Portions created by the Initial Developer are Copyright (C) 1990
 
26
 * the Initial Developer. All Rights Reserved.
 
27
 *
 
28
 * Contributor(s):
 
29
 *
 
30
 * Alternatively, the contents of this file may be used under the terms of
 
31
 * either the GNU General Public License Version 2 or later (the "GPL"), or
 
32
 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 
33
 * in which case the provisions of the GPL or the LGPL are applicable instead
 
34
 * of those above. If you wish to allow use of your version of this file only
 
35
 * under the terms of either the GPL or the LGPL, and not to allow others to
 
36
 * use your version of this file under the terms of the MPL, indicate your
 
37
 * decision by deleting the provisions above and replace them with the notice
 
38
 * and other provisions required by the GPL or the LGPL. If you do not delete
 
39
 * the provisions above, a recipient may use your version of this file under
 
40
 * the terms of any one of the MPL, the GPL or the LGPL.
 
41
 *
 
42
 * ***** END LICENSE BLOCK ***** */
 
43
 
 
44
#include "des.h"
 
45
#include <stddef.h>
 
46
#include "secerr.h"
 
47
 
 
48
#if defined(_X86_)
 
49
/* Intel X86 CPUs do unaligned loads and stores without complaint. */
 
50
#define COPY8B(to, from, ptr) \
 
51
        HALFPTR(to)[0] = HALFPTR(from)[0]; \
 
52
        HALFPTR(to)[1] = HALFPTR(from)[1]; 
 
53
#elif defined(USE_MEMCPY)
 
54
#define COPY8B(to, from, ptr) memcpy(to, from, 8)
 
55
#else
 
56
#define COPY8B(to, from, ptr) \
 
57
    if (((ptrdiff_t)(ptr) & 0x3) == 0) { \
 
58
        HALFPTR(to)[0] = HALFPTR(from)[0]; \
 
59
        HALFPTR(to)[1] = HALFPTR(from)[1]; \
 
60
    } else if (((ptrdiff_t)(ptr) & 0x1) == 0) { \
 
61
        SHORTPTR(to)[0] = SHORTPTR(from)[0]; \
 
62
        SHORTPTR(to)[1] = SHORTPTR(from)[1]; \
 
63
        SHORTPTR(to)[2] = SHORTPTR(from)[2]; \
 
64
        SHORTPTR(to)[3] = SHORTPTR(from)[3]; \
 
65
    } else { \
 
66
        BYTEPTR(to)[0] = BYTEPTR(from)[0]; \
 
67
        BYTEPTR(to)[1] = BYTEPTR(from)[1]; \
 
68
        BYTEPTR(to)[2] = BYTEPTR(from)[2]; \
 
69
        BYTEPTR(to)[3] = BYTEPTR(from)[3]; \
 
70
        BYTEPTR(to)[4] = BYTEPTR(from)[4]; \
 
71
        BYTEPTR(to)[5] = BYTEPTR(from)[5]; \
 
72
        BYTEPTR(to)[6] = BYTEPTR(from)[6]; \
 
73
        BYTEPTR(to)[7] = BYTEPTR(from)[7]; \
 
74
    } 
 
75
#endif
 
76
#define COPY8BTOHALF(to, from) COPY8B(to, from, from)
 
77
#define COPY8BFROMHALF(to, from) COPY8B(to, from, to)
 
78
 
 
79
static void 
 
80
DES_ECB(DESContext *cx, BYTE *out, const BYTE *in, unsigned int len)
 
81
{
 
82
    while (len) {
 
83
        DES_Do1Block(cx->ks0, in, out);
 
84
        len -= 8;
 
85
        in  += 8;
 
86
        out += 8;
 
87
    }
 
88
}
 
89
 
 
90
static void 
 
91
DES_EDE3_ECB(DESContext *cx, BYTE *out, const BYTE *in, unsigned int len)
 
92
{
 
93
    while (len) {
 
94
        DES_Do1Block(cx->ks0,  in, out);
 
95
        len -= 8;
 
96
        in  += 8;
 
97
        DES_Do1Block(cx->ks1, out, out);
 
98
        DES_Do1Block(cx->ks2, out, out);
 
99
        out += 8;
 
100
    }
 
101
}
 
102
 
 
103
static void 
 
104
DES_CBCEn(DESContext *cx, BYTE *out, const BYTE *in, unsigned int len)
 
105
{
 
106
    const BYTE * bufend = in + len;
 
107
    HALF  vec[2];
 
108
 
 
109
    while (in != bufend) {
 
110
        COPY8BTOHALF(vec, in);
 
111
        in += 8;
 
112
        vec[0] ^= cx->iv[0];
 
113
        vec[1] ^= cx->iv[1];
 
114
        DES_Do1Block( cx->ks0, (BYTE *)vec, (BYTE *)cx->iv);
 
115
        COPY8BFROMHALF(out, cx->iv);
 
116
        out += 8;
 
117
    }
 
118
}
 
119
 
 
120
static void 
 
121
DES_CBCDe(DESContext *cx, BYTE *out, const BYTE *in, unsigned int len)
 
122
{
 
123
    const BYTE * bufend;
 
124
    HALF oldciphertext[2];
 
125
    HALF plaintext    [2];
 
126
 
 
127
    for (bufend = in + len; in != bufend; ) {
 
128
        oldciphertext[0] = cx->iv[0];
 
129
        oldciphertext[1] = cx->iv[1];
 
130
        COPY8BTOHALF(cx->iv, in);
 
131
        in += 8;
 
132
        DES_Do1Block(cx->ks0, (BYTE *)cx->iv, (BYTE *)plaintext);
 
133
        plaintext[0] ^= oldciphertext[0];
 
134
        plaintext[1] ^= oldciphertext[1];
 
135
        COPY8BFROMHALF(out, plaintext);
 
136
        out += 8;
 
137
    }
 
138
}
 
139
 
 
140
static void 
 
141
DES_EDE3CBCEn(DESContext *cx, BYTE *out, const BYTE *in, unsigned int len)
 
142
{
 
143
    const BYTE * bufend = in + len;
 
144
    HALF  vec[2];
 
145
 
 
146
    while (in != bufend) {
 
147
        COPY8BTOHALF(vec, in);
 
148
        in += 8;
 
149
        vec[0] ^= cx->iv[0];
 
150
        vec[1] ^= cx->iv[1];
 
151
        DES_Do1Block( cx->ks0, (BYTE *)vec,    (BYTE *)cx->iv);
 
152
        DES_Do1Block( cx->ks1, (BYTE *)cx->iv, (BYTE *)cx->iv);
 
153
        DES_Do1Block( cx->ks2, (BYTE *)cx->iv, (BYTE *)cx->iv);
 
154
        COPY8BFROMHALF(out, cx->iv);
 
155
        out += 8;
 
156
    }
 
157
}
 
158
 
 
159
static void 
 
160
DES_EDE3CBCDe(DESContext *cx, BYTE *out, const BYTE *in, unsigned int len)
 
161
{
 
162
    const BYTE * bufend;
 
163
    HALF oldciphertext[2];
 
164
    HALF plaintext    [2];
 
165
 
 
166
    for (bufend = in + len; in != bufend; ) {
 
167
        oldciphertext[0] = cx->iv[0];
 
168
        oldciphertext[1] = cx->iv[1];
 
169
        COPY8BTOHALF(cx->iv, in);
 
170
        in += 8;
 
171
        DES_Do1Block(cx->ks0, (BYTE *)cx->iv,    (BYTE *)plaintext);
 
172
        DES_Do1Block(cx->ks1, (BYTE *)plaintext, (BYTE *)plaintext);
 
173
        DES_Do1Block(cx->ks2, (BYTE *)plaintext, (BYTE *)plaintext);
 
174
        plaintext[0] ^= oldciphertext[0];
 
175
        plaintext[1] ^= oldciphertext[1];
 
176
        COPY8BFROMHALF(out, plaintext);
 
177
        out += 8;
 
178
    }
 
179
}
 
180
 
 
181
DESContext *
 
182
DES_AllocateContext(void)
 
183
{
 
184
    return PORT_ZNew(DESContext);
 
185
}
 
186
 
 
187
SECStatus   
 
188
DES_InitContext(DESContext *cx, const unsigned char *key, unsigned int keylen,
 
189
                const unsigned char *iv, int mode, unsigned int encrypt,
 
190
                unsigned int unused)
 
191
{
 
192
    DESDirection opposite;
 
193
    if (!cx) {
 
194
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
 
195
        return SECFailure;
 
196
    }
 
197
    cx->direction = encrypt ? DES_ENCRYPT : DES_DECRYPT;
 
198
    opposite      = encrypt ? DES_DECRYPT : DES_ENCRYPT;
 
199
    switch (mode) {
 
200
    case NSS_DES:       /* DES ECB */
 
201
        DES_MakeSchedule( cx->ks0, key, cx->direction);
 
202
        cx->worker = &DES_ECB;
 
203
        break;
 
204
 
 
205
    case NSS_DES_EDE3:  /* DES EDE ECB */
 
206
        cx->worker = &DES_EDE3_ECB;
 
207
        if (encrypt) {
 
208
            DES_MakeSchedule(cx->ks0, key,      cx->direction);
 
209
            DES_MakeSchedule(cx->ks1, key +  8, opposite);
 
210
            DES_MakeSchedule(cx->ks2, key + 16, cx->direction);
 
211
        } else {
 
212
            DES_MakeSchedule(cx->ks2, key,      cx->direction);
 
213
            DES_MakeSchedule(cx->ks1, key +  8, opposite);
 
214
            DES_MakeSchedule(cx->ks0, key + 16, cx->direction);
 
215
        }
 
216
        break;
 
217
 
 
218
    case NSS_DES_CBC:   /* DES CBC */
 
219
        COPY8BTOHALF(cx->iv, iv);
 
220
        cx->worker = encrypt ? &DES_CBCEn : &DES_CBCDe;
 
221
        DES_MakeSchedule(cx->ks0, key, cx->direction);
 
222
        break;
 
223
 
 
224
    case NSS_DES_EDE3_CBC:      /* DES EDE CBC */
 
225
        COPY8BTOHALF(cx->iv, iv);
 
226
        if (encrypt) {
 
227
            cx->worker = &DES_EDE3CBCEn;
 
228
            DES_MakeSchedule(cx->ks0, key,      cx->direction);
 
229
            DES_MakeSchedule(cx->ks1, key +  8, opposite);
 
230
            DES_MakeSchedule(cx->ks2, key + 16, cx->direction);
 
231
        } else {
 
232
            cx->worker = &DES_EDE3CBCDe;
 
233
            DES_MakeSchedule(cx->ks2, key,      cx->direction);
 
234
            DES_MakeSchedule(cx->ks1, key +  8, opposite);
 
235
            DES_MakeSchedule(cx->ks0, key + 16, cx->direction);
 
236
        }
 
237
        break;
 
238
 
 
239
    default:
 
240
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
 
241
        return SECFailure;
 
242
    }
 
243
    return SECSuccess;
 
244
}
 
245
 
 
246
DESContext *
 
247
DES_CreateContext(const BYTE * key, const BYTE *iv, int mode, PRBool encrypt)
 
248
{
 
249
    DESContext *cx = PORT_ZNew(DESContext);
 
250
    SECStatus rv   = DES_InitContext(cx, key, 0, iv, mode, encrypt, 0);
 
251
 
 
252
    if (rv != SECSuccess) {
 
253
        PORT_ZFree(cx, sizeof *cx);
 
254
        cx = NULL;
 
255
    }
 
256
    return cx;
 
257
}
 
258
 
 
259
void
 
260
DES_DestroyContext(DESContext *cx, PRBool freeit)
 
261
{
 
262
    if (cx) {
 
263
        memset(cx, 0, sizeof *cx);
 
264
        if (freeit)
 
265
            PORT_Free(cx);
 
266
    }
 
267
}
 
268
 
 
269
SECStatus
 
270
DES_Encrypt(DESContext *cx, BYTE *out, unsigned int *outLen,
 
271
            unsigned int maxOutLen, const BYTE *in, unsigned int inLen)
 
272
{
 
273
 
 
274
    if (inLen < 0 || (inLen % 8) != 0 || maxOutLen < inLen || !cx || 
 
275
        cx->direction != DES_ENCRYPT) {
 
276
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
 
277
        return SECFailure;
 
278
    }
 
279
 
 
280
    cx->worker(cx, out, in, inLen);
 
281
    if (outLen)
 
282
        *outLen = inLen;
 
283
    return SECSuccess;
 
284
}
 
285
 
 
286
SECStatus
 
287
DES_Decrypt(DESContext *cx, BYTE *out, unsigned int *outLen,
 
288
            unsigned int maxOutLen, const BYTE *in, unsigned int inLen)
 
289
{
 
290
 
 
291
    if (inLen < 0 || (inLen % 8) != 0 || maxOutLen < inLen || !cx || 
 
292
        cx->direction != DES_DECRYPT) {
 
293
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
 
294
        return SECFailure;
 
295
    }
 
296
 
 
297
    cx->worker(cx, out, in, inLen);
 
298
    if (outLen)
 
299
        *outLen = inLen;
 
300
    return SECSuccess;
 
301
}