~ubuntu-branches/ubuntu/precise/kompozer/precise

« back to all changes in this revision

Viewing changes to mozilla/security/nss/cmd/bltest/blapitest.c

  • Committer: Bazaar Package Importer
  • Author(s): Anthony Yarusso
  • Date: 2007-08-27 01:11:03 UTC
  • Revision ID: james.westby@ubuntu.com-20070827011103-2jgf4s6532gqu2ka
Tags: upstream-0.7.10
ImportĀ upstreamĀ versionĀ 0.7.10

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * The contents of this file are subject to the Mozilla Public
 
3
 * License Version 1.1 (the "License"); you may not use this file
 
4
 * except in compliance with the License. You may obtain a copy of
 
5
 * the License at http://www.mozilla.org/MPL/
 
6
 *
 
7
 * Software distributed under the License is distributed on an "AS
 
8
 * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
 
9
 * implied. See the License for the specific language governing
 
10
 * rights and limitations under the License.
 
11
 *
 
12
 * The Original Code is the Netscape security libraries.
 
13
 *
 
14
 * The Initial Developer of the Original Code is Netscape
 
15
 * Communications Corporation.  Portions created by Netscape are
 
16
 * Copyright (C) 1994-2000 Netscape Communications Corporation.  All
 
17
 * Rights Reserved.
 
18
 *
 
19
 * Contributor(s):
 
20
 *      Douglas Stebila <douglas@stebila.ca>, Sun Microsystems Laboratories
 
21
 *
 
22
 * Alternatively, the contents of this file may be used under the
 
23
 * terms of the GNU General Public License Version 2 or later (the
 
24
 * "GPL"), in which case the provisions of the GPL are applicable
 
25
 * instead of those above.  If you wish to allow use of your
 
26
 * version of this file only under the terms of the GPL and not to
 
27
 * allow others to use your version of this file under the MPL,
 
28
 * indicate your decision by deleting the provisions above and
 
29
 * replace them with the notice and other provisions required by
 
30
 * the GPL.  If you do not delete the provisions above, a recipient
 
31
 * may use your version of this file under either the MPL or the
 
32
 * GPL.
 
33
 */
 
34
 
 
35
#include <stdio.h>
 
36
#include <stdlib.h>
 
37
 
 
38
#include "blapi.h"
 
39
#include "secrng.h"
 
40
#include "prmem.h"
 
41
#include "prprf.h"
 
42
#include "prtime.h"
 
43
#include "prsystem.h"
 
44
#include "plstr.h"
 
45
#include "nssb64.h"
 
46
#include "secutil.h"
 
47
#include "plgetopt.h"
 
48
#include "softoken.h"
 
49
#include "nss.h"
 
50
 
 
51
#ifdef NSS_ENABLE_ECC
 
52
#include "ecl-curve.h"
 
53
SECStatus EC_DecodeParams(const SECItem *encodedParams, 
 
54
        ECParams **ecparams);
 
55
SECStatus EC_CopyParams(PRArenaPool *arena, ECParams *dstParams,
 
56
              const ECParams *srcParams);
 
57
SECStatus secoid_Init(void);
 
58
#endif
 
59
 
 
60
/* Temporary - add debugging ouput on windows for RSA to track QA failure */
 
61
#ifdef _WIN32
 
62
#define TRACK_BLTEST_BUG
 
63
    char __bltDBG[] = "BLTEST DEBUG";
 
64
#endif
 
65
 
 
66
char *progName;
 
67
char *testdir = NULL;
 
68
 
 
69
#define BLTEST_DEFAULT_CHUNKSIZE 4096
 
70
 
 
71
#define WORDSIZE sizeof(unsigned long)
 
72
 
 
73
#define CHECKERROR(rv, ln) \
 
74
    if (rv) { \
 
75
        PRErrorCode prerror = PR_GetError(); \
 
76
        PR_fprintf(PR_STDERR, "%s: ERR %d (%s) at line %d.\n", progName, \
 
77
                   prerror, SECU_Strerror(prerror), ln); \
 
78
        exit(-1); \
 
79
    }
 
80
 
 
81
/* Macros for performance timing. */
 
82
#define TIMESTART() \
 
83
    time1 = PR_IntervalNow();
 
84
 
 
85
#define TIMEFINISH(time, reps) \
 
86
    time2 = (PRIntervalTime)(PR_IntervalNow() - time1); \
 
87
    time1 = PR_IntervalToMilliseconds(time2); \
 
88
    time = ((double)(time1))/reps;
 
89
 
 
90
static void Usage()
 
91
{
 
92
#define PRINTUSAGE(subject, option, predicate) \
 
93
    fprintf(stderr, "%10s %s\t%s\n", subject, option, predicate);
 
94
    fprintf(stderr, "\n");
 
95
    PRINTUSAGE(progName, "[-DEHSV]", "List available cipher modes"); /* XXX */
 
96
    fprintf(stderr, "\n");
 
97
    PRINTUSAGE(progName, "-E -m mode ", "Encrypt a buffer");
 
98
    PRINTUSAGE("",      "", "[-i plaintext] [-o ciphertext] [-k key] [-v iv]");
 
99
    PRINTUSAGE("",      "", "[-b bufsize] [-g keysize] [-e exp] [-r rounds]");
 
100
    PRINTUSAGE("",      "", "[-w wordsize] [-p repetitions]");
 
101
    PRINTUSAGE("",      "-m", "cipher mode to use");
 
102
    PRINTUSAGE("",      "-i", "file which contains input buffer");
 
103
    PRINTUSAGE("",      "-o", "file for output buffer");
 
104
    PRINTUSAGE("",      "-k", "file which contains key");
 
105
    PRINTUSAGE("",      "-v", "file which contains initialization vector");
 
106
    PRINTUSAGE("",      "-b", "size of input buffer");
 
107
    PRINTUSAGE("",      "-g", "key size (in bytes)");
 
108
    PRINTUSAGE("",      "-p", "do performance test");
 
109
    PRINTUSAGE("(rsa)", "-e", "rsa public exponent");
 
110
    PRINTUSAGE("(rc5)", "-r", "number of rounds");
 
111
    PRINTUSAGE("(rc5)", "-w", "wordsize (32 or 64)");
 
112
    fprintf(stderr, "\n");
 
113
    PRINTUSAGE(progName, "-D -m mode", "Decrypt a buffer");
 
114
    PRINTUSAGE("",      "", "[-i plaintext] [-o ciphertext] [-k key] [-v iv]");
 
115
    PRINTUSAGE("",      "", "[-p repetitions]");
 
116
    PRINTUSAGE("",      "-m", "cipher mode to use");
 
117
    PRINTUSAGE("",      "-i", "file which contains input buffer");
 
118
    PRINTUSAGE("",      "-o", "file for output buffer");
 
119
    PRINTUSAGE("",      "-k", "file which contains key");
 
120
    PRINTUSAGE("",      "-v", "file which contains initialization vector");
 
121
    PRINTUSAGE("",      "-p", "do performance test");
 
122
    fprintf(stderr, "\n");
 
123
    PRINTUSAGE(progName, "-H -m mode", "Hash a buffer");
 
124
    PRINTUSAGE("",      "", "[-i plaintext] [-o hash]");
 
125
    PRINTUSAGE("",      "", "[-b bufsize]");
 
126
    PRINTUSAGE("",      "", "[-p repetitions]");
 
127
    PRINTUSAGE("",      "-m", "cipher mode to use");
 
128
    PRINTUSAGE("",      "-i", "file which contains input buffer");
 
129
    PRINTUSAGE("",      "-o", "file for hash");
 
130
    PRINTUSAGE("",      "-b", "size of input buffer");
 
131
    PRINTUSAGE("",      "-p", "do performance test");
 
132
    fprintf(stderr, "\n");
 
133
    PRINTUSAGE(progName, "-S -m mode", "Sign a buffer");
 
134
    PRINTUSAGE("",      "", "[-i plaintext] [-o signature] [-k key]");
 
135
    PRINTUSAGE("",      "", "[-b bufsize]");
 
136
#ifdef NSS_ENABLE_ECC
 
137
    PRINTUSAGE("",      "", "[-n curvename]");
 
138
#endif
 
139
    PRINTUSAGE("",      "", "[-p repetitions]");
 
140
    PRINTUSAGE("",      "-m", "cipher mode to use");
 
141
    PRINTUSAGE("",      "-i", "file which contains input buffer");
 
142
    PRINTUSAGE("",      "-o", "file for signature");
 
143
    PRINTUSAGE("",      "-k", "file which contains key");
 
144
#ifdef NSS_ENABLE_ECC
 
145
    PRINTUSAGE("",      "-n", "name of curve for EC key generation; one of:");
 
146
    PRINTUSAGE("",  "",   "  sect163k1, nistk163, sect163r1, sect163r2,");
 
147
    PRINTUSAGE("",  "",   "  nistb163, sect193r1, sect193r2, sect233k1, nistk233,");
 
148
    PRINTUSAGE("",  "",   "  sect233r1, nistb233, sect239k1, sect283k1, nistk283,");
 
149
    PRINTUSAGE("",  "",   "  sect283r1, nistb283, sect409k1, nistk409, sect409r1,");
 
150
    PRINTUSAGE("",  "",   "  nistb409, sect571k1, nistk571, sect571r1, nistb571,");
 
151
    PRINTUSAGE("",  "",   "  secp169k1, secp160r1, secp160r2, secp192k1, secp192r1,");
 
152
    PRINTUSAGE("",  "",   "  nistp192, secp224k1, secp224r1, nistp224, secp256k1,");
 
153
    PRINTUSAGE("",  "",   "  secp256r1, nistp256, secp384r1, nistp384, secp521r1,");
 
154
    PRINTUSAGE("",  "",   "  nistp521, prime192v1, prime192v2, prime192v3,");
 
155
    PRINTUSAGE("",  "",   "  prime239v1, prime239v2, prime239v3, c2pnb163v1,");
 
156
    PRINTUSAGE("",  "",   "  c2pnb163v2, c2pnb163v3, c2pnb176v1, c2tnb191v1,");
 
157
    PRINTUSAGE("",  "",   "  c2tnb191v2, c2tnb191v3, c2onb191v4, c2onb191v5,");
 
158
    PRINTUSAGE("",  "",   "  c2pnb208w1, c2tnb239v1, c2tnb239v2, c2tnb239v3,");
 
159
    PRINTUSAGE("",  "",   "  c2onb239v4, c2onb239v5, c2pnb272w1, c2pnb304w1,");
 
160
    PRINTUSAGE("",  "",   "  c2tnb359w1, c2pnb368w1, c2tnb431r1, secp112r1,");
 
161
    PRINTUSAGE("",  "",   "  secp112r2, secp128r1, secp128r2, sect113r1, sect113r2,");
 
162
    PRINTUSAGE("",  "",   "  sect131r1, sect131r2");
 
163
#endif
 
164
    PRINTUSAGE("",      "-p", "do performance test");
 
165
    fprintf(stderr, "\n");
 
166
    PRINTUSAGE(progName, "-V -m mode", "Verify a signed buffer");
 
167
    PRINTUSAGE("",      "", "[-i plaintext] [-s signature] [-k key]");
 
168
    PRINTUSAGE("",      "", "[-p repetitions]");
 
169
    PRINTUSAGE("",      "-m", "cipher mode to use");
 
170
    PRINTUSAGE("",      "-i", "file which contains input buffer");
 
171
    PRINTUSAGE("",      "-s", "file which contains signature of input buffer");
 
172
    PRINTUSAGE("",      "-k", "file which contains key");
 
173
    PRINTUSAGE("",      "-p", "do performance test");
 
174
    fprintf(stderr, "\n");
 
175
    PRINTUSAGE(progName, "-N -m mode -b bufsize", 
 
176
                                            "Create a nonce plaintext and key");
 
177
    PRINTUSAGE("",      "", "[-g keysize] [-u cxreps]");
 
178
    PRINTUSAGE("",      "-g", "key size (in bytes)");
 
179
    PRINTUSAGE("",      "-u", "number of repetitions of context creation");
 
180
    fprintf(stderr, "\n");
 
181
    PRINTUSAGE(progName, "-F", "Run the FIPS self-test");
 
182
    fprintf(stderr, "\n");
 
183
    PRINTUSAGE(progName, "-T [-m mode1,mode2...]", "Run the BLAPI self-test");
 
184
    fprintf(stderr, "\n");
 
185
    exit(1);
 
186
}
 
187
 
 
188
/*  Helper functions for ascii<-->binary conversion/reading/writing */
 
189
 
 
190
/* XXX argh */
 
191
struct item_with_arena {
 
192
    SECItem     *item;
 
193
    PRArenaPool *arena;
 
194
};
 
195
 
 
196
static PRInt32
 
197
get_binary(void *arg, const unsigned char *ibuf, PRInt32 size)
 
198
{
 
199
    struct item_with_arena *it = arg;
 
200
    SECItem *binary = it->item;
 
201
    SECItem *tmp;
 
202
    int index;
 
203
    if (binary->data == NULL) {
 
204
        tmp = SECITEM_AllocItem(it->arena, NULL, size);
 
205
        binary->data = tmp->data;
 
206
        binary->len = tmp->len;
 
207
        index = 0;
 
208
    } else {
 
209
        SECITEM_ReallocItem(NULL, binary, binary->len, binary->len + size);
 
210
        index = binary->len;
 
211
    }
 
212
    PORT_Memcpy(&binary->data[index], ibuf, size);
 
213
    return binary->len;
 
214
}
 
215
 
 
216
static SECStatus
 
217
atob(SECItem *ascii, SECItem *binary, PRArenaPool *arena)
 
218
{
 
219
    SECStatus status;
 
220
    NSSBase64Decoder *cx;
 
221
    struct item_with_arena it;
 
222
    int len;
 
223
    binary->data = NULL;
 
224
    binary->len = 0;
 
225
    it.item = binary;
 
226
    it.arena = arena;
 
227
    len = (strcmp(&ascii->data[ascii->len-2],"\r\n")) ? 
 
228
           ascii->len : ascii->len-2;
 
229
    cx = NSSBase64Decoder_Create(get_binary, &it);
 
230
    status = NSSBase64Decoder_Update(cx, (const char *)ascii->data, len);
 
231
    status = NSSBase64Decoder_Destroy(cx, PR_FALSE);
 
232
    return status;
 
233
}
 
234
 
 
235
static PRInt32
 
236
output_ascii(void *arg, const char *obuf, PRInt32 size)
 
237
{
 
238
    PRFileDesc *outfile = arg;
 
239
    PRInt32 nb = PR_Write(outfile, obuf, size);
 
240
    if (nb != size) {
 
241
        PORT_SetError(SEC_ERROR_IO);
 
242
        return -1;
 
243
    }
 
244
    return nb;
 
245
}
 
246
 
 
247
static SECStatus
 
248
btoa_file(SECItem *binary, PRFileDesc *outfile)
 
249
{
 
250
    SECStatus status;
 
251
    NSSBase64Encoder *cx;
 
252
    SECItem ascii;
 
253
    ascii.data = NULL;
 
254
    ascii.len = 0;
 
255
    if (binary->len == 0)
 
256
        return SECSuccess;
 
257
    cx = NSSBase64Encoder_Create(output_ascii, outfile);
 
258
    status = NSSBase64Encoder_Update(cx, binary->data, binary->len);
 
259
    status = NSSBase64Encoder_Destroy(cx, PR_FALSE);
 
260
    status = PR_Write(outfile, "\r\n", 2);
 
261
    return status;
 
262
}
 
263
 
 
264
SECStatus
 
265
hex_from_2char(unsigned char *c2, unsigned char *byteval)
 
266
{
 
267
    int i;
 
268
    unsigned char offset;
 
269
    *byteval = 0;
 
270
    for (i=0; i<2; i++) {
 
271
        if (c2[i] >= '0' && c2[i] <= '9') {
 
272
            offset = c2[i] - '0';
 
273
            *byteval |= offset << 4*(1-i);
 
274
        } else if (c2[i] >= 'a' && c2[i] <= 'f') {
 
275
            offset = c2[i] - 'a';
 
276
            *byteval |= (offset + 10) << 4*(1-i);
 
277
        } else if (c2[i] >= 'A' && c2[i] <= 'F') {
 
278
            offset = c2[i] - 'A';
 
279
            *byteval |= (offset + 10) << 4*(1-i);
 
280
        } else {
 
281
            return SECFailure;
 
282
        }
 
283
    }
 
284
    return SECSuccess;
 
285
}
 
286
 
 
287
SECStatus
 
288
char2_from_hex(unsigned char byteval, unsigned char *c2)
 
289
{
 
290
    int i;
 
291
    unsigned char offset;
 
292
    for (i=0; i<2; i++) {
 
293
        offset = (byteval >> 4*(1-i)) & 0x0f;
 
294
        if (offset < 10) {
 
295
            c2[i] = '0' + offset;
 
296
        } else {
 
297
            c2[i] = 'A' + offset - 10;
 
298
        }
 
299
    }
 
300
    return SECSuccess;
 
301
}
 
302
 
 
303
void
 
304
serialize_key(SECItem *it, int ni, PRFileDesc *file)
 
305
{
 
306
    unsigned char len[4];
 
307
    int i;
 
308
    SECStatus status;
 
309
    NSSBase64Encoder *cx;
 
310
    SECItem ascii;
 
311
    ascii.data = NULL;
 
312
    ascii.len = 0;
 
313
    cx = NSSBase64Encoder_Create(output_ascii, file);
 
314
    for (i=0; i<ni; i++, it++) {
 
315
        len[0] = (it->len >> 24) & 0xff;
 
316
        len[1] = (it->len >> 16) & 0xff;
 
317
        len[2] = (it->len >>  8) & 0xff;
 
318
        len[3] = (it->len        & 0xff);
 
319
        status = NSSBase64Encoder_Update(cx, len, 4);
 
320
        status = NSSBase64Encoder_Update(cx, it->data, it->len);
 
321
    }
 
322
    status = NSSBase64Encoder_Destroy(cx, PR_FALSE);
 
323
    status = PR_Write(file, "\r\n", 2);
 
324
}
 
325
 
 
326
void
 
327
key_from_filedata(PRArenaPool *arena, SECItem *it, int ns, int ni, SECItem *filedata)
 
328
{
 
329
    int fpos = 0;
 
330
    int i, len;
 
331
    unsigned char *buf = filedata->data;
 
332
    for (i=0; i<ni; i++) {
 
333
        len  = (buf[fpos++] & 0xff) << 24;
 
334
        len |= (buf[fpos++] & 0xff) << 16;
 
335
        len |= (buf[fpos++] & 0xff) <<  8;
 
336
        len |= (buf[fpos++] & 0xff);
 
337
        if (ns <= i) {
 
338
            if (len > 0) {
 
339
                it->len = len;
 
340
                it->data = PORT_ArenaAlloc(arena, it->len);
 
341
                PORT_Memcpy(it->data, &buf[fpos], it->len);
 
342
            } else {
 
343
                it->len = 0;
 
344
                it->data = NULL;
 
345
            }
 
346
            it++;
 
347
        }
 
348
        fpos += len;
 
349
    }
 
350
}
 
351
 
 
352
static RSAPrivateKey *
 
353
rsakey_from_filedata(SECItem *filedata)
 
354
{
 
355
    RSAPrivateKey *key;
 
356
    PRArenaPool *arena;
 
357
    arena = PORT_NewArena(BLTEST_DEFAULT_CHUNKSIZE);
 
358
    key = (RSAPrivateKey *)PORT_ArenaZAlloc(arena, sizeof(RSAPrivateKey));
 
359
    key->arena = arena;
 
360
    key_from_filedata(arena, &key->version, 0, 9, filedata);
 
361
    return key;
 
362
}
 
363
 
 
364
static PQGParams *
 
365
pqg_from_filedata(SECItem *filedata)
 
366
{
 
367
    PQGParams *pqg;
 
368
    PRArenaPool *arena;
 
369
    arena = PORT_NewArena(BLTEST_DEFAULT_CHUNKSIZE);
 
370
    pqg = (PQGParams *)PORT_ArenaZAlloc(arena, sizeof(PQGParams));
 
371
    pqg->arena = arena;
 
372
    key_from_filedata(arena, &pqg->prime, 0, 3, filedata);
 
373
    return pqg;
 
374
}
 
375
 
 
376
static DSAPrivateKey *
 
377
dsakey_from_filedata(SECItem *filedata)
 
378
{
 
379
    DSAPrivateKey *key;
 
380
    PRArenaPool *arena;
 
381
    arena = PORT_NewArena(BLTEST_DEFAULT_CHUNKSIZE);
 
382
    key = (DSAPrivateKey *)PORT_ArenaZAlloc(arena, sizeof(DSAPrivateKey));
 
383
    key->params.arena = arena;
 
384
    key_from_filedata(arena, &key->params.prime, 0, 5, filedata);
 
385
    return key;
 
386
}
 
387
 
 
388
#ifdef NSS_ENABLE_ECC
 
389
static ECPrivateKey *
 
390
eckey_from_filedata(SECItem *filedata)
 
391
{
 
392
    ECPrivateKey *key;
 
393
    PRArenaPool *arena;
 
394
    SECStatus rv;
 
395
    ECParams *tmpECParams = NULL;
 
396
    arena = PORT_NewArena(BLTEST_DEFAULT_CHUNKSIZE);
 
397
    key = (ECPrivateKey *)PORT_ArenaZAlloc(arena, sizeof(ECPrivateKey));
 
398
    /* read and convert params */
 
399
    key->ecParams.arena = arena;
 
400
    key_from_filedata(arena, &key->ecParams.DEREncoding, 0, 1, filedata);
 
401
    rv = secoid_Init();
 
402
    CHECKERROR(rv, __LINE__);
 
403
    rv = EC_DecodeParams(&key->ecParams.DEREncoding, &tmpECParams);
 
404
    CHECKERROR(rv, __LINE__);
 
405
    rv = EC_CopyParams(key->ecParams.arena, &key->ecParams, tmpECParams);
 
406
    CHECKERROR(rv, __LINE__);
 
407
    rv = SECOID_Shutdown();
 
408
    CHECKERROR(rv, __LINE__);
 
409
    PORT_FreeArena(tmpECParams->arena, PR_TRUE);
 
410
    /* read key */
 
411
    key_from_filedata(arena, &key->publicValue, 1, 3, filedata);
 
412
    return key;
 
413
}
 
414
 
 
415
typedef struct curveNameTagPairStr {
 
416
    char *curveName;
 
417
    SECOidTag curveOidTag;
 
418
} CurveNameTagPair;
 
419
 
 
420
#define DEFAULT_CURVE_OID_TAG  SEC_OID_SECG_EC_SECP192R1
 
421
/* #define DEFAULT_CURVE_OID_TAG  SEC_OID_SECG_EC_SECP160R1 */
 
422
 
 
423
static CurveNameTagPair nameTagPair[] =
 
424
 
425
  { "sect163k1", SEC_OID_SECG_EC_SECT163K1},
 
426
  { "nistk163", SEC_OID_SECG_EC_SECT163K1},
 
427
  { "sect163r1", SEC_OID_SECG_EC_SECT163R1},
 
428
  { "sect163r2", SEC_OID_SECG_EC_SECT163R2},
 
429
  { "nistb163", SEC_OID_SECG_EC_SECT163R2},
 
430
  { "sect193r1", SEC_OID_SECG_EC_SECT193R1},
 
431
  { "sect193r2", SEC_OID_SECG_EC_SECT193R2},
 
432
  { "sect233k1", SEC_OID_SECG_EC_SECT233K1},
 
433
  { "nistk233", SEC_OID_SECG_EC_SECT233K1},
 
434
  { "sect233r1", SEC_OID_SECG_EC_SECT233R1},
 
435
  { "nistb233", SEC_OID_SECG_EC_SECT233R1},
 
436
  { "sect239k1", SEC_OID_SECG_EC_SECT239K1},
 
437
  { "sect283k1", SEC_OID_SECG_EC_SECT283K1},
 
438
  { "nistk283", SEC_OID_SECG_EC_SECT283K1},
 
439
  { "sect283r1", SEC_OID_SECG_EC_SECT283R1},
 
440
  { "nistb283", SEC_OID_SECG_EC_SECT283R1},
 
441
  { "sect409k1", SEC_OID_SECG_EC_SECT409K1},
 
442
  { "nistk409", SEC_OID_SECG_EC_SECT409K1},
 
443
  { "sect409r1", SEC_OID_SECG_EC_SECT409R1},
 
444
  { "nistb409", SEC_OID_SECG_EC_SECT409R1},
 
445
  { "sect571k1", SEC_OID_SECG_EC_SECT571K1},
 
446
  { "nistk571", SEC_OID_SECG_EC_SECT571K1},
 
447
  { "sect571r1", SEC_OID_SECG_EC_SECT571R1},
 
448
  { "nistb571", SEC_OID_SECG_EC_SECT571R1},
 
449
  { "secp160k1", SEC_OID_SECG_EC_SECP160K1},
 
450
  { "secp160r1", SEC_OID_SECG_EC_SECP160R1},
 
451
  { "secp160r2", SEC_OID_SECG_EC_SECP160R2},
 
452
  { "secp192k1", SEC_OID_SECG_EC_SECP192K1},
 
453
  { "secp192r1", SEC_OID_SECG_EC_SECP192R1},
 
454
  { "nistp192", SEC_OID_SECG_EC_SECP192R1},
 
455
  { "secp224k1", SEC_OID_SECG_EC_SECP224K1},
 
456
  { "secp224r1", SEC_OID_SECG_EC_SECP224R1},
 
457
  { "nistp224", SEC_OID_SECG_EC_SECP224R1},
 
458
  { "secp256k1", SEC_OID_SECG_EC_SECP256K1},
 
459
  { "secp256r1", SEC_OID_SECG_EC_SECP256R1},
 
460
  { "nistp256", SEC_OID_SECG_EC_SECP256R1},
 
461
  { "secp384r1", SEC_OID_SECG_EC_SECP384R1},
 
462
  { "nistp384", SEC_OID_SECG_EC_SECP384R1},
 
463
  { "secp521r1", SEC_OID_SECG_EC_SECP521R1},
 
464
  { "nistp521", SEC_OID_SECG_EC_SECP521R1},
 
465
 
 
466
  { "prime192v1", SEC_OID_ANSIX962_EC_PRIME192V1 },
 
467
  { "prime192v2", SEC_OID_ANSIX962_EC_PRIME192V2 },
 
468
  { "prime192v3", SEC_OID_ANSIX962_EC_PRIME192V3 },
 
469
  { "prime239v1", SEC_OID_ANSIX962_EC_PRIME239V1 },
 
470
  { "prime239v2", SEC_OID_ANSIX962_EC_PRIME239V2 },
 
471
  { "prime239v3", SEC_OID_ANSIX962_EC_PRIME239V3 },
 
472
 
 
473
  { "c2pnb163v1", SEC_OID_ANSIX962_EC_C2PNB163V1 },
 
474
  { "c2pnb163v2", SEC_OID_ANSIX962_EC_C2PNB163V2 },
 
475
  { "c2pnb163v3", SEC_OID_ANSIX962_EC_C2PNB163V3 },
 
476
  { "c2pnb176v1", SEC_OID_ANSIX962_EC_C2PNB176V1 },
 
477
  { "c2tnb191v1", SEC_OID_ANSIX962_EC_C2TNB191V1 },
 
478
  { "c2tnb191v2", SEC_OID_ANSIX962_EC_C2TNB191V2 },
 
479
  { "c2tnb191v3", SEC_OID_ANSIX962_EC_C2TNB191V3 },
 
480
  { "c2onb191v4", SEC_OID_ANSIX962_EC_C2ONB191V4 },
 
481
  { "c2onb191v5", SEC_OID_ANSIX962_EC_C2ONB191V5 },
 
482
  { "c2pnb208w1", SEC_OID_ANSIX962_EC_C2PNB208W1 },
 
483
  { "c2tnb239v1", SEC_OID_ANSIX962_EC_C2TNB239V1 },
 
484
  { "c2tnb239v2", SEC_OID_ANSIX962_EC_C2TNB239V2 },
 
485
  { "c2tnb239v3", SEC_OID_ANSIX962_EC_C2TNB239V3 },
 
486
  { "c2onb239v4", SEC_OID_ANSIX962_EC_C2ONB239V4 },
 
487
  { "c2onb239v5", SEC_OID_ANSIX962_EC_C2ONB239V5 },
 
488
  { "c2pnb272w1", SEC_OID_ANSIX962_EC_C2PNB272W1 },
 
489
  { "c2pnb304w1", SEC_OID_ANSIX962_EC_C2PNB304W1 },
 
490
  { "c2tnb359v1", SEC_OID_ANSIX962_EC_C2TNB359V1 },
 
491
  { "c2pnb368w1", SEC_OID_ANSIX962_EC_C2PNB368W1 },
 
492
  { "c2tnb431r1", SEC_OID_ANSIX962_EC_C2TNB431R1 },
 
493
 
 
494
  { "secp112r1", SEC_OID_SECG_EC_SECP112R1},
 
495
  { "secp112r2", SEC_OID_SECG_EC_SECP112R2},
 
496
  { "secp128r1", SEC_OID_SECG_EC_SECP128R1},
 
497
  { "secp128r2", SEC_OID_SECG_EC_SECP128R2},
 
498
 
 
499
  { "sect113r1", SEC_OID_SECG_EC_SECT113R1},
 
500
  { "sect113r2", SEC_OID_SECG_EC_SECT113R2},
 
501
  { "sect131r1", SEC_OID_SECG_EC_SECT131R1},
 
502
  { "sect131r2", SEC_OID_SECG_EC_SECT131R2},
 
503
};
 
504
 
 
505
static SECKEYECParams * 
 
506
getECParams(char *curve)
 
507
{
 
508
    SECKEYECParams *ecparams;
 
509
    SECOidData *oidData = NULL;
 
510
    SECOidTag curveOidTag = SEC_OID_UNKNOWN; /* default */
 
511
    int i, numCurves;
 
512
 
 
513
    if (curve != NULL) {
 
514
        numCurves = sizeof(nameTagPair)/sizeof(CurveNameTagPair);
 
515
        for (i = 0; ((i < numCurves) && (curveOidTag == SEC_OID_UNKNOWN)); 
 
516
             i++) {
 
517
            if (PL_strcmp(curve, nameTagPair[i].curveName) == 0)
 
518
                curveOidTag = nameTagPair[i].curveOidTag;
 
519
        }
 
520
    }
 
521
 
 
522
    /* Return NULL if curve name is not recognized */
 
523
    if ((curveOidTag == SEC_OID_UNKNOWN) || 
 
524
        (oidData = SECOID_FindOIDByTag(curveOidTag)) == NULL) {
 
525
        fprintf(stderr, "Unrecognized elliptic curve %s\n", curve);
 
526
        return NULL;
 
527
    }
 
528
 
 
529
    ecparams = SECITEM_AllocItem(NULL, NULL, (2 + oidData->oid.len));
 
530
 
 
531
    /* 
 
532
     * ecparams->data needs to contain the ASN encoding of an object ID (OID)
 
533
     * representing the named curve. The actual OID is in 
 
534
     * oidData->oid.data so we simply prepend 0x06 and OID length
 
535
     */
 
536
    ecparams->data[0] = SEC_ASN1_OBJECT_ID;
 
537
    ecparams->data[1] = oidData->oid.len;
 
538
    memcpy(ecparams->data + 2, oidData->oid.data, oidData->oid.len);
 
539
 
 
540
    return ecparams;
 
541
}
 
542
#endif /* NSS_ENABLE_ECC */
 
543
 
 
544
static void
 
545
dump_pqg(PQGParams *pqg)
 
546
{
 
547
    SECU_PrintInteger(stdout, &pqg->prime, "PRIME:", 0);
 
548
    SECU_PrintInteger(stdout, &pqg->subPrime, "SUBPRIME:", 0);
 
549
    SECU_PrintInteger(stdout, &pqg->base, "BASE:", 0);
 
550
}
 
551
 
 
552
static void
 
553
dump_dsakey(DSAPrivateKey *key)
 
554
{
 
555
    dump_pqg(&key->params);
 
556
    SECU_PrintInteger(stdout, &key->publicValue, "PUBLIC VALUE:", 0);
 
557
    SECU_PrintInteger(stdout, &key->privateValue, "PRIVATE VALUE:", 0);
 
558
}
 
559
 
 
560
#ifdef NSS_ENABLE_ECC
 
561
static void
 
562
dump_ecp(ECParams *ecp)
 
563
{
 
564
    /* TODO other fields */
 
565
    SECU_PrintInteger(stdout, &ecp->base, "BASE POINT:", 0);
 
566
}
 
567
 
 
568
static void
 
569
dump_eckey(ECPrivateKey *key)
 
570
{
 
571
    dump_ecp(&key->ecParams);
 
572
    SECU_PrintInteger(stdout, &key->publicValue, "PUBLIC VALUE:", 0);
 
573
    SECU_PrintInteger(stdout, &key->privateValue, "PRIVATE VALUE:", 0);
 
574
}
 
575
#endif
 
576
 
 
577
static void
 
578
dump_rsakey(RSAPrivateKey *key)
 
579
{
 
580
    SECU_PrintInteger(stdout, &key->version, "VERSION:", 0);
 
581
    SECU_PrintInteger(stdout, &key->modulus, "MODULUS:", 0);
 
582
    SECU_PrintInteger(stdout, &key->publicExponent, "PUBLIC EXP:", 0);
 
583
    SECU_PrintInteger(stdout, &key->privateExponent, "PRIVATE EXP:", 0);
 
584
    SECU_PrintInteger(stdout, &key->prime1, "CRT PRIME 1:", 0);
 
585
    SECU_PrintInteger(stdout, &key->prime2, "CRT PRIME 2:", 0);
 
586
    SECU_PrintInteger(stdout, &key->exponent1, "CRT EXP 1:", 0);
 
587
    SECU_PrintInteger(stdout, &key->exponent2, "CRT EXP 2:", 0);
 
588
    SECU_PrintInteger(stdout, &key->coefficient, "CRT COEFFICIENT:", 0);
 
589
}
 
590
 
 
591
typedef enum {
 
592
    bltestBase64Encoded,       /* Base64 encoded ASCII */
 
593
    bltestBinary,              /* straight binary */
 
594
    bltestHexSpaceDelim,       /* 0x12 0x34 0xab 0xCD ... */
 
595
    bltestHexStream            /* 1234abCD ... */
 
596
} bltestIOMode;
 
597
 
 
598
typedef struct
 
599
{
 
600
    SECItem        buf;
 
601
    SECItem        pBuf;
 
602
    bltestIOMode   mode;
 
603
    PRFileDesc*    file;
 
604
} bltestIO;
 
605
 
 
606
typedef SECStatus (* bltestSymmCipherFn)(void *cx,
 
607
                                         unsigned char *output,
 
608
                                         unsigned int *outputLen,
 
609
                                         unsigned int maxOutputLen,
 
610
                                         const unsigned char *input,
 
611
                                         unsigned int inputLen);
 
612
 
 
613
typedef SECStatus (* bltestPubKeyCipherFn)(void *key,
 
614
                                           SECItem *output,
 
615
                                           const SECItem *input);
 
616
 
 
617
typedef SECStatus (* bltestHashCipherFn)(unsigned char *dest,
 
618
                                         const unsigned char *src,
 
619
                                         uint32 src_length);
 
620
 
 
621
typedef enum {
 
622
    bltestINVALID = -1,
 
623
    bltestDES_ECB,        /* Symmetric Key Ciphers */
 
624
    bltestDES_CBC,        /* .                     */
 
625
    bltestDES_EDE_ECB,    /* .                     */
 
626
    bltestDES_EDE_CBC,    /* .                     */
 
627
    bltestRC2_ECB,        /* .                     */
 
628
    bltestRC2_CBC,        /* .                     */
 
629
    bltestRC4,            /* .                     */
 
630
    bltestRC5_ECB,        /* .                     */
 
631
    bltestRC5_CBC,        /* .                     */
 
632
    bltestAES_ECB,        /* .                     */
 
633
    bltestAES_CBC,        /* .                     */
 
634
    bltestRSA,            /* Public Key Ciphers    */
 
635
#ifdef NSS_ENABLE_ECC
 
636
    bltestECDSA,          /* . (Public Key Sig.)   */
 
637
#endif
 
638
    bltestDSA,            /* .                     */
 
639
    bltestMD2,            /* Hash algorithms       */
 
640
    bltestMD5,            /* .                     */
 
641
    bltestSHA1,           /* .                     */
 
642
    bltestSHA256,         /* .                     */
 
643
    bltestSHA384,         /* .                     */
 
644
    bltestSHA512,         /* .                     */
 
645
    NUMMODES
 
646
} bltestCipherMode;
 
647
 
 
648
static char *mode_strings[] =
 
649
{
 
650
    "des_ecb",
 
651
    "des_cbc",
 
652
    "des3_ecb",
 
653
    "des3_cbc",
 
654
    "rc2_ecb",
 
655
    "rc2_cbc",
 
656
    "rc4",
 
657
    "rc5_ecb",
 
658
    "rc5_cbc",
 
659
    "aes_ecb",
 
660
    "aes_cbc",
 
661
    "rsa",
 
662
#ifdef NSS_ENABLE_ECC
 
663
    "ecdsa",
 
664
#endif
 
665
    /*"pqg",*/
 
666
    "dsa",
 
667
    "md2",
 
668
    "md5",
 
669
    "sha1",
 
670
    "sha256",
 
671
    "sha384",
 
672
    "sha512",
 
673
};
 
674
 
 
675
typedef struct
 
676
{
 
677
    bltestIO key;
 
678
    bltestIO iv;
 
679
} bltestSymmKeyParams;
 
680
 
 
681
typedef struct
 
682
{
 
683
    bltestIO key;
 
684
    bltestIO iv;
 
685
    int      rounds;
 
686
    int      wordsize;
 
687
} bltestRC5Params;
 
688
 
 
689
typedef struct
 
690
{
 
691
    bltestIO key;
 
692
    int      keysizeInBits;
 
693
    RSAPrivateKey *rsakey;
 
694
} bltestRSAParams;
 
695
 
 
696
typedef struct
 
697
{
 
698
    bltestIO   key;
 
699
    bltestIO   pqgdata;
 
700
    unsigned int j;
 
701
    bltestIO   keyseed;
 
702
    bltestIO   sigseed;
 
703
    bltestIO   sig; /* if doing verify, have additional input */
 
704
    PQGParams *pqg;
 
705
    DSAPrivateKey *dsakey;
 
706
} bltestDSAParams;
 
707
 
 
708
#ifdef NSS_ENABLE_ECC
 
709
typedef struct
 
710
{
 
711
    bltestIO   key;
 
712
    char      *curveName;
 
713
    bltestIO   sigseed;
 
714
    bltestIO   sig; /* if doing verify, have additional input */
 
715
    ECPrivateKey *eckey;
 
716
} bltestECDSAParams;
 
717
#endif
 
718
 
 
719
typedef struct
 
720
{
 
721
    bltestIO   key; /* unused */
 
722
    PRBool     restart;
 
723
} bltestHashParams;
 
724
 
 
725
typedef union
 
726
{
 
727
    bltestIO            key;
 
728
    bltestSymmKeyParams sk;
 
729
    bltestRC5Params     rc5;
 
730
    bltestRSAParams     rsa;
 
731
    bltestDSAParams     dsa;
 
732
#ifdef NSS_ENABLE_ECC
 
733
    bltestECDSAParams   ecdsa;
 
734
#endif
 
735
    bltestHashParams    hash;
 
736
} bltestParams;
 
737
 
 
738
typedef struct
 
739
{
 
740
    PRArenaPool *arena;
 
741
    /* cipher context */
 
742
    void *cx;
 
743
    /* I/O streams */
 
744
    bltestIO input;
 
745
    bltestIO output;
 
746
    /* Cipher-specific parameters */
 
747
    bltestParams params;
 
748
    /* Cipher mode */
 
749
    bltestCipherMode  mode;
 
750
    /* Cipher function (encrypt/decrypt/sign/verify/hash) */
 
751
    union {
 
752
        bltestSymmCipherFn   symmkeyCipher;
 
753
        bltestPubKeyCipherFn pubkeyCipher;
 
754
        bltestHashCipherFn   hashCipher;
 
755
    } cipher;
 
756
    /* performance testing */
 
757
    int   repetitions;
 
758
    int   cxreps;
 
759
    double cxtime;
 
760
    double optime;
 
761
} bltestCipherInfo;
 
762
 
 
763
PRBool
 
764
is_symmkeyCipher(bltestCipherMode mode)
 
765
{
 
766
    /* change as needed! */
 
767
    if (mode >= bltestDES_ECB && mode <= bltestAES_CBC)
 
768
        return PR_TRUE;
 
769
    return PR_FALSE;
 
770
}
 
771
 
 
772
PRBool
 
773
is_pubkeyCipher(bltestCipherMode mode)
 
774
{
 
775
    /* change as needed! */
 
776
    if (mode >= bltestRSA && mode <= bltestDSA)
 
777
        return PR_TRUE;
 
778
    return PR_FALSE;
 
779
}
 
780
 
 
781
PRBool
 
782
is_hashCipher(bltestCipherMode mode)
 
783
{
 
784
    /* change as needed! */
 
785
    if (mode >= bltestMD2 && mode <= bltestSHA512)
 
786
        return PR_TRUE;
 
787
    return PR_FALSE;
 
788
}
 
789
 
 
790
PRBool
 
791
is_sigCipher(bltestCipherMode mode)
 
792
{
 
793
    /* change as needed! */
 
794
#ifdef NSS_ENABLE_ECC
 
795
    if (mode >= bltestECDSA && mode <= bltestDSA)
 
796
#else
 
797
    if (mode >= bltestDSA && mode <= bltestDSA)
 
798
#endif
 
799
        return PR_TRUE;
 
800
    return PR_FALSE;
 
801
}
 
802
 
 
803
PRBool
 
804
cipher_requires_IV(bltestCipherMode mode)
 
805
{
 
806
    /* change as needed! */
 
807
    if (mode == bltestDES_CBC || mode == bltestDES_EDE_CBC ||
 
808
        mode == bltestRC2_CBC || mode == bltestRC5_CBC     ||
 
809
        mode == bltestAES_CBC)
 
810
        return PR_TRUE;
 
811
    return PR_FALSE;
 
812
}
 
813
 
 
814
SECStatus finishIO(bltestIO *output, PRFileDesc *file);
 
815
 
 
816
SECStatus
 
817
setupIO(PRArenaPool *arena, bltestIO *input, PRFileDesc *file,
 
818
        char *str, int numBytes)
 
819
{
 
820
    SECStatus rv = SECSuccess;
 
821
    SECItem fileData;
 
822
    SECItem *in;
 
823
    unsigned char *tok;
 
824
    unsigned int i, j;
 
825
 
 
826
    if (file && (numBytes == 0 || file == PR_STDIN)) {
 
827
        /* grabbing data from a file */
 
828
        rv = SECU_FileToItem(&fileData, file);
 
829
        if (rv != SECSuccess) {
 
830
            PR_Close(file);
 
831
            return SECFailure;
 
832
        }
 
833
        in = &fileData;
 
834
    } else if (str) {
 
835
        /* grabbing data from command line */
 
836
        fileData.data = str;
 
837
        fileData.len = PL_strlen(str);
 
838
        in = &fileData;
 
839
    } else if (file) {
 
840
        /* create nonce */
 
841
        SECITEM_AllocItem(arena, &input->buf, numBytes);
 
842
        RNG_GenerateGlobalRandomBytes(input->buf.data, numBytes);
 
843
        return finishIO(input, file);
 
844
    } else {
 
845
        return SECFailure;
 
846
    }
 
847
 
 
848
    switch (input->mode) {
 
849
    case bltestBase64Encoded:
 
850
        rv = atob(in, &input->buf, arena);
 
851
        break;
 
852
    case bltestBinary:
 
853
        if (in->data[in->len-1] == '\n') --in->len;
 
854
        if (in->data[in->len-1] == '\r') --in->len;
 
855
        SECITEM_CopyItem(arena, &input->buf, in);
 
856
        break;
 
857
    case bltestHexSpaceDelim:
 
858
        SECITEM_AllocItem(arena, &input->buf, in->len/5);
 
859
        for (i=0, j=0; i<in->len; i+=5, j++) {
 
860
            tok = &in->data[i];
 
861
            if (tok[0] != '0' || tok[1] != 'x' || tok[4] != ' ')
 
862
                /* bad hex token */
 
863
                break;
 
864
 
 
865
            rv = hex_from_2char(&tok[2], input->buf.data + j);
 
866
            if (rv)
 
867
                break;
 
868
        }
 
869
        break;
 
870
    case bltestHexStream:
 
871
        SECITEM_AllocItem(arena, &input->buf, in->len/2);
 
872
        for (i=0, j=0; i<in->len; i+=2, j++) {
 
873
            tok = &in->data[i];
 
874
            rv = hex_from_2char(tok, input->buf.data + j);
 
875
            if (rv)
 
876
                break;
 
877
        }
 
878
        break;
 
879
    }
 
880
 
 
881
    if (file)
 
882
        SECITEM_FreeItem(&fileData, PR_FALSE);
 
883
    return rv;
 
884
}
 
885
 
 
886
SECStatus
 
887
finishIO(bltestIO *output, PRFileDesc *file)
 
888
{
 
889
    SECStatus rv = SECSuccess;
 
890
    PRInt32 nb;
 
891
    unsigned char byteval;
 
892
    SECItem *it;
 
893
    char hexstr[5];
 
894
    unsigned int i;
 
895
    if (output->pBuf.len > 0) {
 
896
        it = &output->pBuf;
 
897
    } else {
 
898
        it = &output->buf;
 
899
    }
 
900
    switch (output->mode) {
 
901
    case bltestBase64Encoded:
 
902
        rv = btoa_file(it, file);
 
903
        break;
 
904
    case bltestBinary:
 
905
        nb = PR_Write(file, it->data, it->len);
 
906
        rv = (nb == (PRInt32)it->len) ? SECSuccess : SECFailure;
 
907
        break;
 
908
    case bltestHexSpaceDelim:
 
909
        hexstr[0] = '0';
 
910
        hexstr[1] = 'x';
 
911
        hexstr[4] = ' ';
 
912
        for (i=0; i<it->len; i++) {
 
913
            byteval = it->data[i];
 
914
            rv = char2_from_hex(byteval, hexstr + 2);
 
915
            nb = PR_Write(file, hexstr, 5);
 
916
            if (rv)
 
917
                break;
 
918
        }
 
919
        PR_Write(file, "\n", 1);
 
920
        break;
 
921
    case bltestHexStream:
 
922
        for (i=0; i<it->len; i++) {
 
923
            byteval = it->data[i];
 
924
            rv = char2_from_hex(byteval, hexstr);
 
925
            if (rv)
 
926
                break;
 
927
            nb = PR_Write(file, hexstr, 2);
 
928
        }
 
929
        PR_Write(file, "\n", 1);
 
930
        break;
 
931
    }
 
932
    return rv;
 
933
}
 
934
 
 
935
void
 
936
bltestCopyIO(PRArenaPool *arena, bltestIO *dest, bltestIO *src)
 
937
{
 
938
    SECITEM_CopyItem(arena, &dest->buf, &src->buf);
 
939
    if (src->pBuf.len > 0) {
 
940
        dest->pBuf.len = src->pBuf.len;
 
941
        dest->pBuf.data = dest->buf.data + (src->pBuf.data - src->buf.data);
 
942
    }
 
943
    dest->mode = src->mode;
 
944
    dest->file = src->file;
 
945
}
 
946
 
 
947
void
 
948
misalignBuffer(PRArenaPool *arena, bltestIO *io, int off)
 
949
{
 
950
    ptrdiff_t offset = (ptrdiff_t)io->buf.data % WORDSIZE;
 
951
    int length = io->buf.len;
 
952
    if (offset != off) {
 
953
        SECITEM_ReallocItem(arena, &io->buf, length, length + 2*WORDSIZE);
 
954
        io->buf.len = length + 2*WORDSIZE; /* why doesn't realloc do this? */
 
955
        /* offset may have changed? */
 
956
        offset = (ptrdiff_t)io->buf.data % WORDSIZE;
 
957
        if (offset != off) {
 
958
            memmove(io->buf.data + off, io->buf.data, length);
 
959
            io->pBuf.data = io->buf.data + off;
 
960
            io->pBuf.len = length;
 
961
        } else {
 
962
            io->pBuf.data = io->buf.data;
 
963
            io->pBuf.len = length;
 
964
        }
 
965
    } else {
 
966
        io->pBuf.data = io->buf.data;
 
967
        io->pBuf.len = length;
 
968
    }
 
969
}
 
970
 
 
971
SECStatus
 
972
des_Encrypt(void *cx, unsigned char *output, unsigned int *outputLen,
 
973
            unsigned int maxOutputLen, const unsigned char *input,
 
974
            unsigned int inputLen)
 
975
{
 
976
    return DES_Encrypt((DESContext *)cx, output, outputLen, maxOutputLen,
 
977
                       input, inputLen);
 
978
}
 
979
 
 
980
SECStatus
 
981
des_Decrypt(void *cx, unsigned char *output, unsigned int *outputLen,
 
982
            unsigned int maxOutputLen, const unsigned char *input,
 
983
            unsigned int inputLen)
 
984
{
 
985
    return DES_Decrypt((DESContext *)cx, output, outputLen, maxOutputLen,
 
986
                       input, inputLen);
 
987
}
 
988
 
 
989
SECStatus
 
990
rc2_Encrypt(void *cx, unsigned char *output, unsigned int *outputLen,
 
991
            unsigned int maxOutputLen, const unsigned char *input,
 
992
            unsigned int inputLen)
 
993
{
 
994
    return RC2_Encrypt((RC2Context *)cx, output, outputLen, maxOutputLen,
 
995
                       input, inputLen);
 
996
}
 
997
 
 
998
SECStatus
 
999
rc2_Decrypt(void *cx, unsigned char *output, unsigned int *outputLen,
 
1000
            unsigned int maxOutputLen, const unsigned char *input,
 
1001
            unsigned int inputLen)
 
1002
{
 
1003
    return RC2_Decrypt((RC2Context *)cx, output, outputLen, maxOutputLen,
 
1004
                       input, inputLen);
 
1005
}
 
1006
 
 
1007
SECStatus
 
1008
rc4_Encrypt(void *cx, unsigned char *output, unsigned int *outputLen,
 
1009
            unsigned int maxOutputLen, const unsigned char *input,
 
1010
            unsigned int inputLen)
 
1011
{
 
1012
    return RC4_Encrypt((RC4Context *)cx, output, outputLen, maxOutputLen,
 
1013
                       input, inputLen);
 
1014
}
 
1015
 
 
1016
SECStatus
 
1017
rc4_Decrypt(void *cx, unsigned char *output, unsigned int *outputLen,
 
1018
            unsigned int maxOutputLen, const unsigned char *input,
 
1019
            unsigned int inputLen)
 
1020
{
 
1021
    return RC4_Decrypt((RC4Context *)cx, output, outputLen, maxOutputLen,
 
1022
                       input, inputLen);
 
1023
}
 
1024
 
 
1025
SECStatus
 
1026
aes_Encrypt(void *cx, unsigned char *output, unsigned int *outputLen,
 
1027
            unsigned int maxOutputLen, const unsigned char *input,
 
1028
            unsigned int inputLen)
 
1029
{
 
1030
    return AES_Encrypt((AESContext *)cx, output, outputLen, maxOutputLen,
 
1031
                       input, inputLen);
 
1032
}
 
1033
 
 
1034
SECStatus
 
1035
aes_Decrypt(void *cx, unsigned char *output, unsigned int *outputLen,
 
1036
            unsigned int maxOutputLen, const unsigned char *input,
 
1037
            unsigned int inputLen)
 
1038
{
 
1039
    return AES_Decrypt((AESContext *)cx, output, outputLen, maxOutputLen,
 
1040
                       input, inputLen);
 
1041
}
 
1042
 
 
1043
SECStatus
 
1044
rsa_PublicKeyOp(void *key, SECItem *output, const SECItem *input)
 
1045
{
 
1046
    return RSA_PublicKeyOp((RSAPublicKey *)key, output->data, input->data);
 
1047
}
 
1048
 
 
1049
SECStatus
 
1050
rsa_PrivateKeyOp(void *key, SECItem *output, const SECItem *input)
 
1051
{
 
1052
    return RSA_PrivateKeyOp((RSAPrivateKey *)key, output->data, input->data);
 
1053
}
 
1054
 
 
1055
SECStatus
 
1056
dsa_signDigest(void *key, SECItem *output, const SECItem *input)
 
1057
{
 
1058
    return DSA_SignDigest((DSAPrivateKey *)key, output, input);
 
1059
}
 
1060
 
 
1061
SECStatus
 
1062
dsa_verifyDigest(void *key, SECItem *output, const SECItem *input)
 
1063
{
 
1064
    return DSA_VerifyDigest((DSAPublicKey *)key, output, input);
 
1065
}
 
1066
 
 
1067
#ifdef NSS_ENABLE_ECC
 
1068
SECStatus
 
1069
ecdsa_signDigest(void *key, SECItem *output, const SECItem *input)
 
1070
{
 
1071
    return ECDSA_SignDigest((ECPrivateKey *)key, output, input);
 
1072
}
 
1073
 
 
1074
SECStatus
 
1075
ecdsa_verifyDigest(void *key, SECItem *output, const SECItem *input)
 
1076
{
 
1077
    return ECDSA_VerifyDigest((ECPublicKey *)key, output, input);
 
1078
}
 
1079
#endif
 
1080
 
 
1081
SECStatus
 
1082
bltest_des_init(bltestCipherInfo *cipherInfo, PRBool encrypt)
 
1083
{
 
1084
    PRIntervalTime time1, time2;
 
1085
    bltestSymmKeyParams *desp = &cipherInfo->params.sk;
 
1086
    int minorMode;
 
1087
    int i;
 
1088
    switch (cipherInfo->mode) {
 
1089
    case bltestDES_ECB:     minorMode = NSS_DES;          break;
 
1090
    case bltestDES_CBC:     minorMode = NSS_DES_CBC;      break;
 
1091
    case bltestDES_EDE_ECB: minorMode = NSS_DES_EDE3;     break;
 
1092
    case bltestDES_EDE_CBC: minorMode = NSS_DES_EDE3_CBC; break;
 
1093
    default:
 
1094
        return SECFailure;
 
1095
    }
 
1096
    cipherInfo->cx = (void*)DES_CreateContext(desp->key.buf.data,
 
1097
                                              desp->iv.buf.data,
 
1098
                                              minorMode, encrypt);
 
1099
    if (cipherInfo->cxreps > 0) {
 
1100
        DESContext **dummycx;
 
1101
        dummycx = PORT_Alloc(cipherInfo->cxreps * sizeof(DESContext *));
 
1102
        TIMESTART();
 
1103
        for (i=0; i<cipherInfo->cxreps; i++) {
 
1104
            dummycx[i] = (void*)DES_CreateContext(desp->key.buf.data,
 
1105
                                                  desp->iv.buf.data,
 
1106
                                                  minorMode, encrypt);
 
1107
        }
 
1108
        TIMEFINISH(cipherInfo->cxtime, 1.0);
 
1109
        for (i=0; i<cipherInfo->cxreps; i++) {
 
1110
            DES_DestroyContext(dummycx[i], PR_TRUE);
 
1111
        }
 
1112
        PORT_Free(dummycx);
 
1113
    }
 
1114
    if (encrypt)
 
1115
        cipherInfo->cipher.symmkeyCipher = des_Encrypt;
 
1116
    else
 
1117
        cipherInfo->cipher.symmkeyCipher = des_Decrypt;
 
1118
    return SECSuccess;
 
1119
}
 
1120
 
 
1121
SECStatus
 
1122
bltest_rc2_init(bltestCipherInfo *cipherInfo, PRBool encrypt)
 
1123
{
 
1124
    PRIntervalTime time1, time2;
 
1125
    bltestSymmKeyParams *rc2p = &cipherInfo->params.sk;
 
1126
    int minorMode;
 
1127
    int i;
 
1128
    switch (cipherInfo->mode) {
 
1129
    case bltestRC2_ECB: minorMode = NSS_RC2;     break;
 
1130
    case bltestRC2_CBC: minorMode = NSS_RC2_CBC; break;
 
1131
    default:
 
1132
        return SECFailure;
 
1133
    }
 
1134
    cipherInfo->cx = (void*)RC2_CreateContext(rc2p->key.buf.data,
 
1135
                                              rc2p->key.buf.len,
 
1136
                                              rc2p->iv.buf.data,
 
1137
                                              minorMode,
 
1138
                                              rc2p->key.buf.len);
 
1139
    if (cipherInfo->cxreps > 0) {
 
1140
        RC2Context **dummycx;
 
1141
        dummycx = PORT_Alloc(cipherInfo->cxreps * sizeof(RC2Context *));
 
1142
        TIMESTART();
 
1143
        for (i=0; i<cipherInfo->cxreps; i++) {
 
1144
            dummycx[i] = (void*)RC2_CreateContext(rc2p->key.buf.data,
 
1145
                                                  rc2p->key.buf.len,
 
1146
                                                  rc2p->iv.buf.data,
 
1147
                                                  minorMode,
 
1148
                                                  rc2p->key.buf.len);
 
1149
        }
 
1150
        TIMEFINISH(cipherInfo->cxtime, 1.0);
 
1151
        for (i=0; i<cipherInfo->cxreps; i++) {
 
1152
            RC2_DestroyContext(dummycx[i], PR_TRUE);
 
1153
        }
 
1154
        PORT_Free(dummycx);
 
1155
    }
 
1156
    if (encrypt)
 
1157
        cipherInfo->cipher.symmkeyCipher = rc2_Encrypt;
 
1158
    else
 
1159
        cipherInfo->cipher.symmkeyCipher = rc2_Decrypt;
 
1160
    return SECSuccess;
 
1161
}
 
1162
 
 
1163
SECStatus
 
1164
bltest_rc4_init(bltestCipherInfo *cipherInfo, PRBool encrypt)
 
1165
{
 
1166
    PRIntervalTime time1, time2;
 
1167
    int i;
 
1168
    bltestSymmKeyParams *rc4p = &cipherInfo->params.sk;
 
1169
    cipherInfo->cx = (void*)RC4_CreateContext(rc4p->key.buf.data,
 
1170
                                              rc4p->key.buf.len);
 
1171
    if (cipherInfo->cxreps > 0) {
 
1172
        RC4Context **dummycx;
 
1173
        dummycx = PORT_Alloc(cipherInfo->cxreps * sizeof(RC4Context *));
 
1174
        TIMESTART();
 
1175
        for (i=0; i<cipherInfo->cxreps; i++) {
 
1176
            dummycx[i] = (void*)RC4_CreateContext(rc4p->key.buf.data,
 
1177
                                                  rc4p->key.buf.len);
 
1178
        }
 
1179
        TIMEFINISH(cipherInfo->cxtime, 1.0);
 
1180
        for (i=0; i<cipherInfo->cxreps; i++) {
 
1181
            RC4_DestroyContext(dummycx[i], PR_TRUE);
 
1182
        }
 
1183
        PORT_Free(dummycx);
 
1184
    }
 
1185
    if (encrypt)
 
1186
        cipherInfo->cipher.symmkeyCipher = rc4_Encrypt;
 
1187
    else
 
1188
        cipherInfo->cipher.symmkeyCipher = rc4_Decrypt;
 
1189
    return SECSuccess;
 
1190
}
 
1191
 
 
1192
SECStatus
 
1193
bltest_rc5_init(bltestCipherInfo *cipherInfo, PRBool encrypt)
 
1194
{
 
1195
#if NSS_SOFTOKEN_DOES_RC5
 
1196
    PRIntervalTime time1, time2;
 
1197
    bltestRC5Params *rc5p = &cipherInfo->params.rc5;
 
1198
    int minorMode;
 
1199
    switch (cipherInfo->mode) {
 
1200
    case bltestRC5_ECB: minorMode = NSS_RC5;     break;
 
1201
    case bltestRC5_CBC: minorMode = NSS_RC5_CBC; break;
 
1202
    default:
 
1203
        return SECFailure;
 
1204
    }
 
1205
    TIMESTART();
 
1206
    cipherInfo->cx = (void*)RC5_CreateContext(&rc5p->key.buf,
 
1207
                                              rc5p->rounds, rc5p->wordsize,
 
1208
                                              rc5p->iv.buf.data, minorMode);
 
1209
    TIMEFINISH(cipherInfo->cxtime, 1.0);
 
1210
    if (encrypt)
 
1211
        cipherInfo->cipher.symmkeyCipher = RC5_Encrypt;
 
1212
    else
 
1213
        cipherInfo->cipher.symmkeyCipher = RC5_Decrypt;
 
1214
    return SECSuccess;
 
1215
#else
 
1216
    return SECFailure;
 
1217
#endif
 
1218
}
 
1219
 
 
1220
SECStatus
 
1221
bltest_aes_init(bltestCipherInfo *cipherInfo, PRBool encrypt)
 
1222
{
 
1223
    PRIntervalTime time1, time2;
 
1224
    bltestSymmKeyParams *aesp = &cipherInfo->params.sk;
 
1225
    int minorMode;
 
1226
    int i;
 
1227
    /* XXX */ int keylen, blocklen;
 
1228
    keylen = aesp->key.buf.len;
 
1229
    blocklen = cipherInfo->input.pBuf.len;
 
1230
    switch (cipherInfo->mode) {
 
1231
    case bltestAES_ECB:     minorMode = NSS_AES;          break;
 
1232
    case bltestAES_CBC:     minorMode = NSS_AES_CBC;      break;
 
1233
    default:
 
1234
        return SECFailure;
 
1235
    }
 
1236
    cipherInfo->cx = (void*)AES_CreateContext(aesp->key.buf.data,
 
1237
                                              aesp->iv.buf.data,
 
1238
                                              minorMode, encrypt, 
 
1239
                                              keylen, blocklen);
 
1240
    if (cipherInfo->cxreps > 0) {
 
1241
        AESContext **dummycx;
 
1242
        dummycx = PORT_Alloc(cipherInfo->cxreps * sizeof(AESContext *));
 
1243
        TIMESTART();
 
1244
        for (i=0; i<cipherInfo->cxreps; i++) {
 
1245
            dummycx[i] = (void*)AES_CreateContext(aesp->key.buf.data,
 
1246
                                                  aesp->iv.buf.data,
 
1247
                                                  minorMode, encrypt,
 
1248
                                                  keylen, blocklen);
 
1249
        }
 
1250
        TIMEFINISH(cipherInfo->cxtime, 1.0);
 
1251
        for (i=0; i<cipherInfo->cxreps; i++) {
 
1252
            AES_DestroyContext(dummycx[i], PR_TRUE);
 
1253
        }
 
1254
        PORT_Free(dummycx);
 
1255
    }
 
1256
    if (encrypt)
 
1257
        cipherInfo->cipher.symmkeyCipher = aes_Encrypt;
 
1258
    else
 
1259
        cipherInfo->cipher.symmkeyCipher = aes_Decrypt;
 
1260
    return SECSuccess;
 
1261
}
 
1262
 
 
1263
SECStatus
 
1264
bltest_rsa_init(bltestCipherInfo *cipherInfo, PRBool encrypt)
 
1265
{
 
1266
    int i;
 
1267
    RSAPrivateKey **dummyKey;
 
1268
    PRIntervalTime time1, time2;
 
1269
    bltestRSAParams *rsap = &cipherInfo->params.rsa;
 
1270
    /* RSA key gen was done during parameter setup */
 
1271
    cipherInfo->cx = cipherInfo->params.rsa.rsakey;
 
1272
    /* For performance testing */
 
1273
    if (cipherInfo->cxreps > 0) {
 
1274
        /* Create space for n private key objects */
 
1275
        dummyKey = (RSAPrivateKey **)PORT_Alloc(cipherInfo->cxreps *
 
1276
                                                sizeof(RSAPrivateKey *));
 
1277
        /* Time n keygens, storing in the array */
 
1278
        TIMESTART();
 
1279
        for (i=0; i<cipherInfo->cxreps; i++)
 
1280
            dummyKey[i] = RSA_NewKey(rsap->keysizeInBits, 
 
1281
                                     &rsap->rsakey->publicExponent);
 
1282
        TIMEFINISH(cipherInfo->cxtime, cipherInfo->cxreps);
 
1283
        /* Free the n key objects */
 
1284
        for (i=0; i<cipherInfo->cxreps; i++)
 
1285
            PORT_FreeArena(dummyKey[i]->arena, PR_TRUE);
 
1286
        PORT_Free(dummyKey);
 
1287
    }
 
1288
    if (encrypt) {
 
1289
        /* Have to convert private key to public key.  Memory
 
1290
         * is freed with private key's arena  */
 
1291
        RSAPublicKey *pubkey;
 
1292
        RSAPrivateKey *key = (RSAPrivateKey *)cipherInfo->cx;
 
1293
        pubkey = (RSAPublicKey *)PORT_ArenaAlloc(key->arena,
 
1294
                                                 sizeof(RSAPublicKey));
 
1295
        pubkey->modulus.len = key->modulus.len;
 
1296
        pubkey->modulus.data = key->modulus.data;
 
1297
        pubkey->publicExponent.len = key->publicExponent.len;
 
1298
        pubkey->publicExponent.data = key->publicExponent.data;
 
1299
        cipherInfo->cx = (void *)pubkey;
 
1300
        cipherInfo->cipher.pubkeyCipher = rsa_PublicKeyOp;
 
1301
    } else {
 
1302
        cipherInfo->cipher.pubkeyCipher = rsa_PrivateKeyOp;
 
1303
    }
 
1304
    return SECSuccess;
 
1305
}
 
1306
 
 
1307
SECStatus
 
1308
bltest_pqg_init(bltestDSAParams *dsap)
 
1309
{
 
1310
    SECStatus rv, res;
 
1311
    PQGVerify *vfy = NULL;
 
1312
    rv = PQG_ParamGen(dsap->j, &dsap->pqg, &vfy);
 
1313
    CHECKERROR(rv, __LINE__);
 
1314
    rv = PQG_VerifyParams(dsap->pqg, vfy, &res);
 
1315
    CHECKERROR(res, __LINE__);
 
1316
    CHECKERROR(rv, __LINE__);
 
1317
    return rv;
 
1318
}
 
1319
 
 
1320
SECStatus
 
1321
bltest_dsa_init(bltestCipherInfo *cipherInfo, PRBool encrypt)
 
1322
{
 
1323
    int i;
 
1324
    DSAPrivateKey **dummyKey;
 
1325
    PQGParams *dummypqg;
 
1326
    PRIntervalTime time1, time2;
 
1327
    bltestDSAParams *dsap = &cipherInfo->params.dsa;
 
1328
    PQGVerify *ignore = NULL;
 
1329
    /* DSA key gen was done during parameter setup */
 
1330
    cipherInfo->cx = cipherInfo->params.dsa.dsakey;
 
1331
    /* For performance testing */
 
1332
    if (cipherInfo->cxreps > 0) {
 
1333
        /* Create space for n private key objects */
 
1334
        dummyKey = (DSAPrivateKey **)PORT_ZAlloc(cipherInfo->cxreps *
 
1335
                                                 sizeof(DSAPrivateKey *));
 
1336
        /* Time n keygens, storing in the array */
 
1337
        TIMESTART();
 
1338
        for (i=0; i<cipherInfo->cxreps; i++) {
 
1339
            dummypqg = NULL;
 
1340
            PQG_ParamGen(dsap->j, &dummypqg, &ignore);
 
1341
            DSA_NewKey(dummypqg, &dummyKey[i]);
 
1342
        }
 
1343
        TIMEFINISH(cipherInfo->cxtime, cipherInfo->cxreps);
 
1344
        /* Free the n key objects */
 
1345
        for (i=0; i<cipherInfo->cxreps; i++)
 
1346
            PORT_FreeArena(dummyKey[i]->params.arena, PR_TRUE);
 
1347
        PORT_Free(dummyKey);
 
1348
    }
 
1349
    if (!dsap->pqg && dsap->pqgdata.buf.len > 0) {
 
1350
        dsap->pqg = pqg_from_filedata(&dsap->pqgdata.buf);
 
1351
    }
 
1352
    if (!cipherInfo->cx && dsap->key.buf.len > 0) {
 
1353
        cipherInfo->cx = dsakey_from_filedata(&dsap->key.buf);
 
1354
    }
 
1355
    if (encrypt) {
 
1356
        cipherInfo->cipher.pubkeyCipher = dsa_signDigest;
 
1357
    } else {
 
1358
        /* Have to convert private key to public key.  Memory
 
1359
         * is freed with private key's arena  */
 
1360
        DSAPublicKey *pubkey;
 
1361
        DSAPrivateKey *key = (DSAPrivateKey *)cipherInfo->cx;
 
1362
        pubkey = (DSAPublicKey *)PORT_ArenaZAlloc(key->params.arena,
 
1363
                                                  sizeof(DSAPublicKey));
 
1364
        pubkey->params.prime.len = key->params.prime.len;
 
1365
        pubkey->params.prime.data = key->params.prime.data;
 
1366
        pubkey->params.subPrime.len = key->params.subPrime.len;
 
1367
        pubkey->params.subPrime.data = key->params.subPrime.data;
 
1368
        pubkey->params.base.len = key->params.base.len;
 
1369
        pubkey->params.base.data = key->params.base.data;
 
1370
        pubkey->publicValue.len = key->publicValue.len;
 
1371
        pubkey->publicValue.data = key->publicValue.data;
 
1372
        cipherInfo->cipher.pubkeyCipher = dsa_verifyDigest;
 
1373
    }
 
1374
    return SECSuccess;
 
1375
}
 
1376
 
 
1377
#ifdef NSS_ENABLE_ECC
 
1378
SECStatus
 
1379
bltest_ecdsa_init(bltestCipherInfo *cipherInfo, PRBool encrypt)
 
1380
{
 
1381
    int i;
 
1382
    ECPrivateKey **dummyKey;
 
1383
    PRIntervalTime time1, time2;
 
1384
    bltestECDSAParams *ecdsap = &cipherInfo->params.ecdsa;
 
1385
    /* ECDSA key gen was done during parameter setup */
 
1386
    cipherInfo->cx = cipherInfo->params.ecdsa.eckey;
 
1387
    /* For performance testing */
 
1388
    if (cipherInfo->cxreps > 0) {
 
1389
        /* Create space for n private key objects */
 
1390
        dummyKey = (ECPrivateKey **)PORT_ZAlloc(cipherInfo->cxreps *
 
1391
                                                 sizeof(ECPrivateKey *));
 
1392
        /* Time n keygens, storing in the array */
 
1393
        TIMESTART();
 
1394
        for (i=0; i<cipherInfo->cxreps; i++) {
 
1395
            EC_NewKey(&ecdsap->eckey->ecParams, &dummyKey[i]);
 
1396
        }
 
1397
        TIMEFINISH(cipherInfo->cxtime, cipherInfo->cxreps);
 
1398
        /* Free the n key objects */
 
1399
        for (i=0; i<cipherInfo->cxreps; i++)
 
1400
            PORT_FreeArena(dummyKey[i]->ecParams.arena, PR_TRUE);
 
1401
        PORT_Free(dummyKey);
 
1402
    }
 
1403
    if (!cipherInfo->cx && ecdsap->key.buf.len > 0) {
 
1404
        cipherInfo->cx = eckey_from_filedata(&ecdsap->key.buf);
 
1405
    }
 
1406
    if (encrypt) {
 
1407
        cipherInfo->cipher.pubkeyCipher = ecdsa_signDigest;
 
1408
    } else {
 
1409
        /* Have to convert private key to public key.  Memory
 
1410
         * is freed with private key's arena  */
 
1411
        ECPublicKey *pubkey;
 
1412
        ECPrivateKey *key = (ECPrivateKey *)cipherInfo->cx;
 
1413
        pubkey = (ECPublicKey *)PORT_ArenaZAlloc(key->ecParams.arena,
 
1414
                                                  sizeof(ECPublicKey));
 
1415
        pubkey->ecParams.type = key->ecParams.type;
 
1416
        pubkey->ecParams.fieldID.size = key->ecParams.fieldID.size;
 
1417
        pubkey->ecParams.fieldID.type = key->ecParams.fieldID.type;
 
1418
        pubkey->ecParams.fieldID.u.prime.len = key->ecParams.fieldID.u.prime.len;
 
1419
        pubkey->ecParams.fieldID.u.prime.data = key->ecParams.fieldID.u.prime.data;
 
1420
        pubkey->ecParams.fieldID.k1 = key->ecParams.fieldID.k1;
 
1421
        pubkey->ecParams.fieldID.k2 = key->ecParams.fieldID.k2;
 
1422
        pubkey->ecParams.fieldID.k3 = key->ecParams.fieldID.k3;
 
1423
        pubkey->ecParams.curve.a.len = key->ecParams.curve.a.len;
 
1424
        pubkey->ecParams.curve.a.data = key->ecParams.curve.a.data;
 
1425
        pubkey->ecParams.curve.b.len = key->ecParams.curve.b.len;
 
1426
        pubkey->ecParams.curve.b.data = key->ecParams.curve.b.data;
 
1427
        pubkey->ecParams.curve.seed.len = key->ecParams.curve.seed.len;
 
1428
        pubkey->ecParams.curve.seed.data = key->ecParams.curve.seed.data;
 
1429
        pubkey->ecParams.base.len = key->ecParams.base.len;
 
1430
        pubkey->ecParams.base.data = key->ecParams.base.data;
 
1431
        pubkey->ecParams.order.len = key->ecParams.order.len;
 
1432
        pubkey->ecParams.order.data = key->ecParams.order.data;
 
1433
        pubkey->ecParams.cofactor = key->ecParams.cofactor;
 
1434
        pubkey->ecParams.DEREncoding.len = key->ecParams.DEREncoding.len;
 
1435
        pubkey->ecParams.DEREncoding.data = key->ecParams.DEREncoding.data;
 
1436
        pubkey->ecParams.name= key->ecParams.name;
 
1437
        pubkey->publicValue.len = key->publicValue.len;
 
1438
        pubkey->publicValue.data = key->publicValue.data;
 
1439
        cipherInfo->cipher.pubkeyCipher = ecdsa_verifyDigest;
 
1440
    }
 
1441
    return SECSuccess;
 
1442
}
 
1443
#endif
 
1444
 
 
1445
/* XXX unfortunately, this is not defined in blapi.h */
 
1446
SECStatus
 
1447
md2_HashBuf(unsigned char *dest, const unsigned char *src, uint32 src_length)
 
1448
{
 
1449
    unsigned int len;
 
1450
    MD2Context *cx = MD2_NewContext();
 
1451
    if (cx == NULL) return SECFailure;
 
1452
    MD2_Begin(cx);
 
1453
    MD2_Update(cx, src, src_length);
 
1454
    MD2_End(cx, dest, &len, MD2_LENGTH);
 
1455
    MD2_DestroyContext(cx, PR_TRUE);
 
1456
    return SECSuccess;
 
1457
}
 
1458
 
 
1459
SECStatus
 
1460
md2_restart(unsigned char *dest, const unsigned char *src, uint32 src_length)
 
1461
{
 
1462
    MD2Context *cx, *cx_cpy;
 
1463
    unsigned char *cxbytes;
 
1464
    unsigned int len;
 
1465
    unsigned int i, quarter;
 
1466
    SECStatus rv = SECSuccess;
 
1467
    cx = MD2_NewContext();
 
1468
    MD2_Begin(cx);
 
1469
    /* divide message by 4, restarting 3 times */
 
1470
    quarter = (src_length + 3)/ 4;
 
1471
    for (i=0; i < 4 && src_length > 0; i++) {
 
1472
        MD2_Update(cx, src + i*quarter, PR_MIN(quarter, src_length));
 
1473
        len = MD2_FlattenSize(cx);
 
1474
        cxbytes = PORT_Alloc(len);
 
1475
        MD2_Flatten(cx, cxbytes);
 
1476
        cx_cpy = MD2_Resurrect(cxbytes, NULL);
 
1477
        if (!cx_cpy) {
 
1478
            PR_fprintf(PR_STDERR, "%s: MD2_Resurrect failed!\n", progName);
 
1479
            goto finish;
 
1480
        }
 
1481
        rv = PORT_Memcmp(cx, cx_cpy, len);
 
1482
        if (rv) {
 
1483
            MD2_DestroyContext(cx_cpy, PR_TRUE);
 
1484
            PR_fprintf(PR_STDERR, "%s: MD2_restart failed!\n", progName);
 
1485
            goto finish;
 
1486
        }
 
1487
        MD2_DestroyContext(cx_cpy, PR_TRUE);
 
1488
        PORT_Free(cxbytes);
 
1489
        src_length -= quarter;
 
1490
    }
 
1491
    MD2_End(cx, dest, &len, MD2_LENGTH);
 
1492
finish:
 
1493
    MD2_DestroyContext(cx, PR_TRUE);
 
1494
    return rv;
 
1495
}
 
1496
 
 
1497
SECStatus
 
1498
md5_restart(unsigned char *dest, const unsigned char *src, uint32 src_length)
 
1499
{
 
1500
    SECStatus rv = SECSuccess;
 
1501
    MD5Context *cx, *cx_cpy;
 
1502
    unsigned char *cxbytes;
 
1503
    unsigned int len;
 
1504
    unsigned int i, quarter;
 
1505
    cx = MD5_NewContext();
 
1506
    MD5_Begin(cx);
 
1507
    /* divide message by 4, restarting 3 times */
 
1508
    quarter = (src_length + 3)/ 4;
 
1509
    for (i=0; i < 4 && src_length > 0; i++) {
 
1510
        MD5_Update(cx, src + i*quarter, PR_MIN(quarter, src_length));
 
1511
        len = MD5_FlattenSize(cx);
 
1512
        cxbytes = PORT_Alloc(len);
 
1513
        MD5_Flatten(cx, cxbytes);
 
1514
        cx_cpy = MD5_Resurrect(cxbytes, NULL);
 
1515
        if (!cx_cpy) {
 
1516
            PR_fprintf(PR_STDERR, "%s: MD5_Resurrect failed!\n", progName);
 
1517
            rv = SECFailure;
 
1518
            goto finish;
 
1519
        }
 
1520
        rv = PORT_Memcmp(cx, cx_cpy, len);
 
1521
        if (rv) {
 
1522
            MD5_DestroyContext(cx_cpy, PR_TRUE);
 
1523
            PR_fprintf(PR_STDERR, "%s: MD5_restart failed!\n", progName);
 
1524
            goto finish;
 
1525
        }
 
1526
        MD5_DestroyContext(cx_cpy, PR_TRUE);
 
1527
        PORT_Free(cxbytes);
 
1528
        src_length -= quarter;
 
1529
    }
 
1530
    MD5_End(cx, dest, &len, MD5_LENGTH);
 
1531
finish:
 
1532
    MD5_DestroyContext(cx, PR_TRUE);
 
1533
    return rv;
 
1534
}
 
1535
 
 
1536
SECStatus
 
1537
sha1_restart(unsigned char *dest, const unsigned char *src, uint32 src_length)
 
1538
{
 
1539
    SECStatus rv = SECSuccess;
 
1540
    SHA1Context *cx, *cx_cpy;
 
1541
    unsigned char *cxbytes;
 
1542
    unsigned int len;
 
1543
    unsigned int i, quarter;
 
1544
    cx = SHA1_NewContext();
 
1545
    SHA1_Begin(cx);
 
1546
    /* divide message by 4, restarting 3 times */
 
1547
    quarter = (src_length + 3)/ 4;
 
1548
    for (i=0; i < 4 && src_length > 0; i++) {
 
1549
        SHA1_Update(cx, src + i*quarter, PR_MIN(quarter, src_length));
 
1550
        len = SHA1_FlattenSize(cx);
 
1551
        cxbytes = PORT_Alloc(len);
 
1552
        SHA1_Flatten(cx, cxbytes);
 
1553
        cx_cpy = SHA1_Resurrect(cxbytes, NULL);
 
1554
        if (!cx_cpy) {
 
1555
            PR_fprintf(PR_STDERR, "%s: SHA1_Resurrect failed!\n", progName);
 
1556
            rv = SECFailure;
 
1557
            goto finish;
 
1558
        }
 
1559
        rv = PORT_Memcmp(cx, cx_cpy, len);
 
1560
        if (rv) {
 
1561
            SHA1_DestroyContext(cx_cpy, PR_TRUE);
 
1562
            PR_fprintf(PR_STDERR, "%s: SHA1_restart failed!\n", progName);
 
1563
            goto finish;
 
1564
        }
 
1565
        SHA1_DestroyContext(cx_cpy, PR_TRUE);
 
1566
        PORT_Free(cxbytes);
 
1567
        src_length -= quarter;
 
1568
    }
 
1569
    SHA1_End(cx, dest, &len, MD5_LENGTH);
 
1570
finish:
 
1571
    SHA1_DestroyContext(cx, PR_TRUE);
 
1572
    return rv;
 
1573
}
 
1574
 
 
1575
SECStatus
 
1576
SHA256_restart(unsigned char *dest, const unsigned char *src, uint32 src_length)
 
1577
{
 
1578
    SECStatus rv = SECSuccess;
 
1579
    SHA256Context *cx, *cx_cpy;
 
1580
    unsigned char *cxbytes;
 
1581
    unsigned int len;
 
1582
    unsigned int i, quarter;
 
1583
    cx = SHA256_NewContext();
 
1584
    SHA256_Begin(cx);
 
1585
    /* divide message by 4, restarting 3 times */
 
1586
    quarter = (src_length + 3)/ 4;
 
1587
    for (i=0; i < 4 && src_length > 0; i++) {
 
1588
        SHA256_Update(cx, src + i*quarter, PR_MIN(quarter, src_length));
 
1589
        len = SHA256_FlattenSize(cx);
 
1590
        cxbytes = PORT_Alloc(len);
 
1591
        SHA256_Flatten(cx, cxbytes);
 
1592
        cx_cpy = SHA256_Resurrect(cxbytes, NULL);
 
1593
        if (!cx_cpy) {
 
1594
            PR_fprintf(PR_STDERR, "%s: SHA256_Resurrect failed!\n", progName);
 
1595
            rv = SECFailure;
 
1596
            goto finish;
 
1597
        }
 
1598
        rv = PORT_Memcmp(cx, cx_cpy, len);
 
1599
        if (rv) {
 
1600
            SHA256_DestroyContext(cx_cpy, PR_TRUE);
 
1601
            PR_fprintf(PR_STDERR, "%s: SHA256_restart failed!\n", progName);
 
1602
            goto finish;
 
1603
        }
 
1604
        SHA256_DestroyContext(cx_cpy, PR_TRUE);
 
1605
        PORT_Free(cxbytes);
 
1606
        src_length -= quarter;
 
1607
    }
 
1608
    SHA256_End(cx, dest, &len, MD5_LENGTH);
 
1609
finish:
 
1610
    SHA256_DestroyContext(cx, PR_TRUE);
 
1611
    return rv;
 
1612
}
 
1613
 
 
1614
SECStatus
 
1615
SHA384_restart(unsigned char *dest, const unsigned char *src, uint32 src_length)
 
1616
{
 
1617
    SECStatus rv = SECSuccess;
 
1618
    SHA384Context *cx, *cx_cpy;
 
1619
    unsigned char *cxbytes;
 
1620
    unsigned int len;
 
1621
    unsigned int i, quarter;
 
1622
    cx = SHA384_NewContext();
 
1623
    SHA384_Begin(cx);
 
1624
    /* divide message by 4, restarting 3 times */
 
1625
    quarter = (src_length + 3)/ 4;
 
1626
    for (i=0; i < 4 && src_length > 0; i++) {
 
1627
        SHA384_Update(cx, src + i*quarter, PR_MIN(quarter, src_length));
 
1628
        len = SHA384_FlattenSize(cx);
 
1629
        cxbytes = PORT_Alloc(len);
 
1630
        SHA384_Flatten(cx, cxbytes);
 
1631
        cx_cpy = SHA384_Resurrect(cxbytes, NULL);
 
1632
        if (!cx_cpy) {
 
1633
            PR_fprintf(PR_STDERR, "%s: SHA384_Resurrect failed!\n", progName);
 
1634
            rv = SECFailure;
 
1635
            goto finish;
 
1636
        }
 
1637
        rv = PORT_Memcmp(cx, cx_cpy, len);
 
1638
        if (rv) {
 
1639
            SHA384_DestroyContext(cx_cpy, PR_TRUE);
 
1640
            PR_fprintf(PR_STDERR, "%s: SHA384_restart failed!\n", progName);
 
1641
            goto finish;
 
1642
        }
 
1643
        SHA384_DestroyContext(cx_cpy, PR_TRUE);
 
1644
        PORT_Free(cxbytes);
 
1645
        src_length -= quarter;
 
1646
    }
 
1647
    SHA384_End(cx, dest, &len, MD5_LENGTH);
 
1648
finish:
 
1649
    SHA384_DestroyContext(cx, PR_TRUE);
 
1650
    return rv;
 
1651
}
 
1652
 
 
1653
SECStatus
 
1654
SHA512_restart(unsigned char *dest, const unsigned char *src, uint32 src_length)
 
1655
{
 
1656
    SECStatus rv = SECSuccess;
 
1657
    SHA512Context *cx, *cx_cpy;
 
1658
    unsigned char *cxbytes;
 
1659
    unsigned int len;
 
1660
    unsigned int i, quarter;
 
1661
    cx = SHA512_NewContext();
 
1662
    SHA512_Begin(cx);
 
1663
    /* divide message by 4, restarting 3 times */
 
1664
    quarter = (src_length + 3)/ 4;
 
1665
    for (i=0; i < 4 && src_length > 0; i++) {
 
1666
        SHA512_Update(cx, src + i*quarter, PR_MIN(quarter, src_length));
 
1667
        len = SHA512_FlattenSize(cx);
 
1668
        cxbytes = PORT_Alloc(len);
 
1669
        SHA512_Flatten(cx, cxbytes);
 
1670
        cx_cpy = SHA512_Resurrect(cxbytes, NULL);
 
1671
        if (!cx_cpy) {
 
1672
            PR_fprintf(PR_STDERR, "%s: SHA512_Resurrect failed!\n", progName);
 
1673
            rv = SECFailure;
 
1674
            goto finish;
 
1675
        }
 
1676
        rv = PORT_Memcmp(cx, cx_cpy, len);
 
1677
        if (rv) {
 
1678
            SHA512_DestroyContext(cx_cpy, PR_TRUE);
 
1679
            PR_fprintf(PR_STDERR, "%s: SHA512_restart failed!\n", progName);
 
1680
            goto finish;
 
1681
        }
 
1682
        SHA512_DestroyContext(cx_cpy, PR_TRUE);
 
1683
        PORT_Free(cxbytes);
 
1684
        src_length -= quarter;
 
1685
    }
 
1686
    SHA512_End(cx, dest, &len, MD5_LENGTH);
 
1687
finish:
 
1688
    SHA512_DestroyContext(cx, PR_TRUE);
 
1689
    return rv;
 
1690
}
 
1691
 
 
1692
SECStatus
 
1693
pubkeyInitKey(bltestCipherInfo *cipherInfo, PRFileDesc *file,
 
1694
#ifdef NSS_ENABLE_ECC
 
1695
              int keysize, int exponent, char *curveName)
 
1696
#else
 
1697
              int keysize, int exponent)
 
1698
#endif
 
1699
{
 
1700
    int i;
 
1701
    SECStatus rv = SECSuccess;
 
1702
    bltestRSAParams *rsap;
 
1703
    bltestDSAParams *dsap;
 
1704
#ifdef NSS_ENABLE_ECC
 
1705
    bltestECDSAParams *ecdsap;
 
1706
    SECItem *tmpECParamsDER;
 
1707
    ECParams *tmpECParams = NULL;
 
1708
    SECItem ecSerialize[3];
 
1709
#endif
 
1710
    switch (cipherInfo->mode) {
 
1711
    case bltestRSA:
 
1712
        rsap = &cipherInfo->params.rsa;
 
1713
        if (keysize > 0) {
 
1714
            SECItem expitem = { 0, 0, 0 };
 
1715
            SECITEM_AllocItem(cipherInfo->arena, &expitem, sizeof(int));
 
1716
            for (i = 1; i <= sizeof(int); i++)
 
1717
                expitem.data[i-1] = exponent >> (8*(sizeof(int) - i));
 
1718
            rsap->rsakey = RSA_NewKey(keysize * 8, &expitem);
 
1719
            serialize_key(&rsap->rsakey->version, 9, file);
 
1720
            rsap->keysizeInBits = keysize * 8;
 
1721
        } else {
 
1722
            setupIO(cipherInfo->arena, &cipherInfo->params.key, file, NULL, 0);
 
1723
            rsap->rsakey = rsakey_from_filedata(&cipherInfo->params.key.buf);
 
1724
            rsap->keysizeInBits = rsap->rsakey->modulus.len * 8;
 
1725
        }
 
1726
        break;
 
1727
    case bltestDSA:
 
1728
        dsap = &cipherInfo->params.dsa;
 
1729
        if (keysize > 0) {
 
1730
            dsap->j = PQG_PBITS_TO_INDEX(8*keysize);
 
1731
            if (!dsap->pqg)
 
1732
                bltest_pqg_init(dsap);
 
1733
            rv = DSA_NewKey(dsap->pqg, &dsap->dsakey);
 
1734
            CHECKERROR(rv, __LINE__);
 
1735
            serialize_key(&dsap->dsakey->params.prime, 5, file);
 
1736
        } else {
 
1737
            setupIO(cipherInfo->arena, &cipherInfo->params.key, file, NULL, 0);
 
1738
            dsap->dsakey = dsakey_from_filedata(&cipherInfo->params.key.buf);
 
1739
            dsap->j = PQG_PBITS_TO_INDEX(8*dsap->dsakey->params.prime.len);
 
1740
        }
 
1741
        break;
 
1742
#ifdef NSS_ENABLE_ECC
 
1743
    case bltestECDSA:
 
1744
        ecdsap = &cipherInfo->params.ecdsa;
 
1745
        if (curveName != NULL) {
 
1746
            tmpECParamsDER = getECParams(curveName);
 
1747
            rv = secoid_Init();
 
1748
            CHECKERROR(rv, __LINE__);
 
1749
            rv = EC_DecodeParams(tmpECParamsDER, &tmpECParams) == SECFailure;
 
1750
            CHECKERROR(rv, __LINE__);
 
1751
            rv = EC_NewKey(tmpECParams, &ecdsap->eckey);
 
1752
            CHECKERROR(rv, __LINE__);
 
1753
            ecSerialize[0].type = tmpECParamsDER->type;
 
1754
            ecSerialize[0].data = tmpECParamsDER->data;
 
1755
            ecSerialize[0].len  = tmpECParamsDER->len;
 
1756
            ecSerialize[1].type = ecdsap->eckey->publicValue.type;
 
1757
            ecSerialize[1].data = ecdsap->eckey->publicValue.data;
 
1758
            ecSerialize[1].len  = ecdsap->eckey->publicValue.len;
 
1759
            ecSerialize[2].type = ecdsap->eckey->privateValue.type;
 
1760
            ecSerialize[2].data = ecdsap->eckey->privateValue.data;
 
1761
            ecSerialize[2].len  = ecdsap->eckey->privateValue.len;
 
1762
            serialize_key(&(ecSerialize[0]), 3, file);
 
1763
            free(tmpECParamsDER);
 
1764
            PORT_FreeArena(tmpECParams->arena, PR_TRUE);
 
1765
            rv = SECOID_Shutdown();
 
1766
            CHECKERROR(rv, __LINE__);
 
1767
        } else {
 
1768
            setupIO(cipherInfo->arena, &cipherInfo->params.key, file, NULL, 0);
 
1769
            ecdsap->eckey = eckey_from_filedata(&cipherInfo->params.key.buf);
 
1770
        }
 
1771
        break;
 
1772
#endif
 
1773
    default:
 
1774
        return SECFailure;
 
1775
    }
 
1776
    return SECSuccess;
 
1777
}
 
1778
 
 
1779
SECStatus
 
1780
cipherInit(bltestCipherInfo *cipherInfo, PRBool encrypt)
 
1781
{
 
1782
    PRBool restart;
 
1783
    switch (cipherInfo->mode) {
 
1784
    case bltestDES_ECB:
 
1785
    case bltestDES_CBC:
 
1786
    case bltestDES_EDE_ECB:
 
1787
    case bltestDES_EDE_CBC:
 
1788
        SECITEM_AllocItem(cipherInfo->arena, &cipherInfo->output.buf,
 
1789
                          cipherInfo->input.pBuf.len);
 
1790
        return bltest_des_init(cipherInfo, encrypt);
 
1791
        break;
 
1792
    case bltestRC2_ECB:
 
1793
    case bltestRC2_CBC:
 
1794
        SECITEM_AllocItem(cipherInfo->arena, &cipherInfo->output.buf,
 
1795
                          cipherInfo->input.pBuf.len);
 
1796
        return bltest_rc2_init(cipherInfo, encrypt);
 
1797
        break;
 
1798
    case bltestRC4:
 
1799
        SECITEM_AllocItem(cipherInfo->arena, &cipherInfo->output.buf,
 
1800
                          cipherInfo->input.pBuf.len);
 
1801
        return bltest_rc4_init(cipherInfo, encrypt);
 
1802
        break;
 
1803
    case bltestRC5_ECB:
 
1804
    case bltestRC5_CBC:
 
1805
#if NSS_SOFTOKEN_DOES_RC5
 
1806
        SECITEM_AllocItem(cipherInfo->arena, &cipherInfo->output.buf,
 
1807
                          cipherInfo->input.pBuf.len);
 
1808
#endif
 
1809
        return bltest_rc5_init(cipherInfo, encrypt);
 
1810
        break;
 
1811
    case bltestAES_ECB:
 
1812
    case bltestAES_CBC:
 
1813
        SECITEM_AllocItem(cipherInfo->arena, &cipherInfo->output.buf,
 
1814
                          cipherInfo->input.pBuf.len);
 
1815
        return bltest_aes_init(cipherInfo, encrypt);
 
1816
        break;
 
1817
    case bltestRSA:
 
1818
        SECITEM_AllocItem(cipherInfo->arena, &cipherInfo->output.buf,
 
1819
                          cipherInfo->input.pBuf.len);
 
1820
        return bltest_rsa_init(cipherInfo, encrypt);
 
1821
        break;
 
1822
    case bltestDSA:
 
1823
        SECITEM_AllocItem(cipherInfo->arena, &cipherInfo->output.buf,
 
1824
                          DSA_SIGNATURE_LEN);
 
1825
        return bltest_dsa_init(cipherInfo, encrypt);
 
1826
        break;
 
1827
#ifdef NSS_ENABLE_ECC
 
1828
    case bltestECDSA:
 
1829
        SECITEM_AllocItem(cipherInfo->arena, &cipherInfo->output.buf,
 
1830
                          2 * MAX_ECKEY_LEN);
 
1831
        return bltest_ecdsa_init(cipherInfo, encrypt);
 
1832
        break;
 
1833
#endif
 
1834
    case bltestMD2:
 
1835
        restart = cipherInfo->params.hash.restart;
 
1836
        SECITEM_AllocItem(cipherInfo->arena, &cipherInfo->output.buf,
 
1837
                          MD2_LENGTH);
 
1838
        cipherInfo->cipher.hashCipher = (restart) ? md2_restart : md2_HashBuf;
 
1839
        return SECSuccess;
 
1840
        break;
 
1841
    case bltestMD5:
 
1842
        restart = cipherInfo->params.hash.restart;
 
1843
        SECITEM_AllocItem(cipherInfo->arena, &cipherInfo->output.buf,
 
1844
                          MD5_LENGTH);
 
1845
        cipherInfo->cipher.hashCipher = (restart) ? md5_restart : MD5_HashBuf;
 
1846
        return SECSuccess;
 
1847
        break;
 
1848
    case bltestSHA1:
 
1849
        restart = cipherInfo->params.hash.restart;
 
1850
        SECITEM_AllocItem(cipherInfo->arena, &cipherInfo->output.buf,
 
1851
                          SHA1_LENGTH);
 
1852
        cipherInfo->cipher.hashCipher = (restart) ? sha1_restart : SHA1_HashBuf;
 
1853
        return SECSuccess;
 
1854
        break;
 
1855
    case bltestSHA256:
 
1856
        restart = cipherInfo->params.hash.restart;
 
1857
        SECITEM_AllocItem(cipherInfo->arena, &cipherInfo->output.buf,
 
1858
                          SHA256_LENGTH);
 
1859
        cipherInfo->cipher.hashCipher = (restart) ? SHA256_restart 
 
1860
                                                  : SHA256_HashBuf;
 
1861
        return SECSuccess;
 
1862
        break;
 
1863
    case bltestSHA384:
 
1864
        restart = cipherInfo->params.hash.restart;
 
1865
        SECITEM_AllocItem(cipherInfo->arena, &cipherInfo->output.buf,
 
1866
                          SHA384_LENGTH);
 
1867
        cipherInfo->cipher.hashCipher = (restart) ? SHA384_restart 
 
1868
                                                  : SHA384_HashBuf;
 
1869
        return SECSuccess;
 
1870
        break;
 
1871
    case bltestSHA512:
 
1872
        restart = cipherInfo->params.hash.restart;
 
1873
        SECITEM_AllocItem(cipherInfo->arena, &cipherInfo->output.buf,
 
1874
                          SHA512_LENGTH);
 
1875
        cipherInfo->cipher.hashCipher = (restart) ? SHA512_restart 
 
1876
                                                  : SHA512_HashBuf;
 
1877
        return SECSuccess;
 
1878
        break;
 
1879
    default:
 
1880
        return SECFailure;
 
1881
    }
 
1882
    return SECSuccess;
 
1883
}
 
1884
 
 
1885
SECStatus
 
1886
dsaOp(bltestCipherInfo *cipherInfo)
 
1887
{
 
1888
    PRIntervalTime time1, time2;
 
1889
    SECStatus rv = SECSuccess;
 
1890
    int i;
 
1891
    int maxLen = cipherInfo->output.pBuf.len;
 
1892
    SECItem dummyOut = { 0, 0, 0 };
 
1893
    SECITEM_AllocItem(NULL, &dummyOut, maxLen);
 
1894
    if (cipherInfo->cipher.pubkeyCipher == dsa_signDigest) {
 
1895
        if (cipherInfo->params.dsa.sigseed.buf.len > 0) {
 
1896
            rv = DSA_SignDigestWithSeed((DSAPrivateKey *)cipherInfo->cx,
 
1897
                                       &cipherInfo->output.pBuf,
 
1898
                                       &cipherInfo->input.pBuf,
 
1899
                                       cipherInfo->params.dsa.sigseed.buf.data);
 
1900
            CHECKERROR(rv, __LINE__);
 
1901
            TIMESTART();
 
1902
            for (i=0; i<cipherInfo->repetitions; i++) {
 
1903
                rv |= DSA_SignDigestWithSeed((DSAPrivateKey *)cipherInfo->cx,
 
1904
                                       &dummyOut,
 
1905
                                       &cipherInfo->input.pBuf,
 
1906
                                       cipherInfo->params.dsa.sigseed.buf.data);
 
1907
            }
 
1908
            TIMEFINISH(cipherInfo->optime, 1.0);
 
1909
            CHECKERROR(rv, __LINE__);
 
1910
        } else {
 
1911
            rv = DSA_SignDigest((DSAPrivateKey *)cipherInfo->cx,
 
1912
                                &cipherInfo->output.pBuf,
 
1913
                                &cipherInfo->input.pBuf);
 
1914
            CHECKERROR(rv, __LINE__);
 
1915
            TIMESTART();
 
1916
            for (i=0; i<cipherInfo->repetitions; i++) {
 
1917
                DSA_SignDigest((DSAPrivateKey *)cipherInfo->cx, &dummyOut,
 
1918
                               &cipherInfo->input.pBuf);
 
1919
            }
 
1920
            TIMEFINISH(cipherInfo->optime, 1.0);
 
1921
        }
 
1922
        bltestCopyIO(cipherInfo->arena, &cipherInfo->params.dsa.sig, 
 
1923
                     &cipherInfo->output);
 
1924
    } else {
 
1925
        rv = DSA_VerifyDigest((DSAPublicKey *)cipherInfo->cx,
 
1926
                              &cipherInfo->params.dsa.sig.buf,
 
1927
                              &cipherInfo->input.pBuf);
 
1928
        CHECKERROR(rv, __LINE__);
 
1929
        TIMESTART();
 
1930
        for (i=0; i<cipherInfo->repetitions; i++) {
 
1931
            DSA_VerifyDigest((DSAPublicKey *)cipherInfo->cx,
 
1932
                             &cipherInfo->params.dsa.sig.buf,
 
1933
                             &cipherInfo->input.pBuf);
 
1934
        }
 
1935
        TIMEFINISH(cipherInfo->optime, 1.0);
 
1936
    }
 
1937
    SECITEM_FreeItem(&dummyOut, PR_FALSE);
 
1938
    return rv;
 
1939
}
 
1940
 
 
1941
#ifdef NSS_ENABLE_ECC
 
1942
SECStatus
 
1943
ecdsaOp(bltestCipherInfo *cipherInfo)
 
1944
{
 
1945
    PRIntervalTime time1, time2;
 
1946
    SECStatus rv = SECSuccess;
 
1947
    int i;
 
1948
    int maxLen = cipherInfo->output.pBuf.len;
 
1949
    SECItem dummyOut = { 0, 0, 0 };
 
1950
    SECITEM_AllocItem(NULL, &dummyOut, maxLen);
 
1951
    if (cipherInfo->cipher.pubkeyCipher == ecdsa_signDigest) {
 
1952
        if (cipherInfo->params.ecdsa.sigseed.buf.len > 0) {
 
1953
            rv = ECDSA_SignDigestWithSeed((ECPrivateKey *)cipherInfo->cx,
 
1954
                                       &cipherInfo->output.pBuf,
 
1955
                                       &cipherInfo->input.pBuf,
 
1956
                                       cipherInfo->params.ecdsa.sigseed.buf.data,
 
1957
                                       cipherInfo->params.ecdsa.sigseed.buf.len);
 
1958
            CHECKERROR(rv, __LINE__);
 
1959
            TIMESTART();
 
1960
            for (i=0; i<cipherInfo->repetitions; i++) {
 
1961
                rv |= ECDSA_SignDigestWithSeed((ECPrivateKey *)cipherInfo->cx,
 
1962
                                       &dummyOut,
 
1963
                                       &cipherInfo->input.pBuf,
 
1964
                                       cipherInfo->params.ecdsa.sigseed.buf.data,
 
1965
                                       cipherInfo->params.ecdsa.sigseed.buf.len);
 
1966
            }
 
1967
            TIMEFINISH(cipherInfo->optime, 1.0);
 
1968
            CHECKERROR(rv, __LINE__);
 
1969
        } else {
 
1970
            rv = ECDSA_SignDigest((ECPrivateKey *)cipherInfo->cx,
 
1971
                                &cipherInfo->output.pBuf,
 
1972
                                &cipherInfo->input.pBuf);
 
1973
            CHECKERROR(rv, __LINE__);
 
1974
            TIMESTART();
 
1975
            for (i=0; i<cipherInfo->repetitions; i++) {
 
1976
                ECDSA_SignDigest((ECPrivateKey *)cipherInfo->cx, &dummyOut,
 
1977
                               &cipherInfo->input.pBuf);
 
1978
            }
 
1979
            TIMEFINISH(cipherInfo->optime, 1.0);
 
1980
        }
 
1981
        bltestCopyIO(cipherInfo->arena, &cipherInfo->params.ecdsa.sig, 
 
1982
                     &cipherInfo->output);
 
1983
    } else {
 
1984
        rv = ECDSA_VerifyDigest((ECPublicKey *)cipherInfo->cx,
 
1985
                              &cipherInfo->params.ecdsa.sig.buf,
 
1986
                              &cipherInfo->input.pBuf);
 
1987
        CHECKERROR(rv, __LINE__);
 
1988
        TIMESTART();
 
1989
        for (i=0; i<cipherInfo->repetitions; i++) {
 
1990
            ECDSA_VerifyDigest((ECPublicKey *)cipherInfo->cx,
 
1991
                             &cipherInfo->params.ecdsa.sig.buf,
 
1992
                             &cipherInfo->input.pBuf);
 
1993
        }
 
1994
        TIMEFINISH(cipherInfo->optime, 1.0);
 
1995
    }
 
1996
    SECITEM_FreeItem(&dummyOut, PR_FALSE);
 
1997
    return rv;
 
1998
}
 
1999
#endif
 
2000
 
 
2001
SECStatus
 
2002
cipherDoOp(bltestCipherInfo *cipherInfo)
 
2003
{
 
2004
    PRIntervalTime time1, time2;
 
2005
    SECStatus rv = SECSuccess;
 
2006
    int i, len;
 
2007
    int maxLen = cipherInfo->output.pBuf.len;
 
2008
    unsigned char *dummyOut;
 
2009
    if (cipherInfo->mode == bltestDSA)
 
2010
        return dsaOp(cipherInfo);
 
2011
#ifdef NSS_ENABLE_ECC
 
2012
    else if (cipherInfo->mode == bltestECDSA)
 
2013
        return ecdsaOp(cipherInfo);
 
2014
#endif
 
2015
    dummyOut = PORT_Alloc(maxLen);
 
2016
    if (is_symmkeyCipher(cipherInfo->mode)) {
 
2017
        rv = (*cipherInfo->cipher.symmkeyCipher)(cipherInfo->cx,
 
2018
                                                 cipherInfo->output.pBuf.data,
 
2019
                                                 &len, maxLen,
 
2020
                                                 cipherInfo->input.pBuf.data,
 
2021
                                                 cipherInfo->input.pBuf.len);
 
2022
        TIMESTART();
 
2023
        for (i=0; i<cipherInfo->repetitions; i++) {
 
2024
            (*cipherInfo->cipher.symmkeyCipher)(cipherInfo->cx, dummyOut,
 
2025
                                                &len, maxLen,
 
2026
                                                cipherInfo->input.pBuf.data,
 
2027
                                                cipherInfo->input.pBuf.len);
 
2028
 
 
2029
        }
 
2030
        TIMEFINISH(cipherInfo->optime, 1.0);
 
2031
    } else if (is_pubkeyCipher(cipherInfo->mode)) {
 
2032
        rv = (*cipherInfo->cipher.pubkeyCipher)(cipherInfo->cx,
 
2033
                                                &cipherInfo->output.pBuf,
 
2034
                                                &cipherInfo->input.pBuf);
 
2035
        TIMESTART();
 
2036
        for (i=0; i<cipherInfo->repetitions; i++) {
 
2037
            SECItem dummy;
 
2038
            dummy.data = dummyOut;
 
2039
            dummy.len = maxLen;
 
2040
            (*cipherInfo->cipher.pubkeyCipher)(cipherInfo->cx, &dummy,
 
2041
                                               &cipherInfo->input.pBuf);
 
2042
        }
 
2043
        TIMEFINISH(cipherInfo->optime, 1.0);
 
2044
    } else if (is_hashCipher(cipherInfo->mode)) {
 
2045
        rv = (*cipherInfo->cipher.hashCipher)(cipherInfo->output.pBuf.data,
 
2046
                                              cipherInfo->input.pBuf.data,
 
2047
                                              cipherInfo->input.pBuf.len);
 
2048
        TIMESTART();
 
2049
        for (i=0; i<cipherInfo->repetitions; i++) {
 
2050
            (*cipherInfo->cipher.hashCipher)(dummyOut,
 
2051
                                             cipherInfo->input.pBuf.data,
 
2052
                                             cipherInfo->input.pBuf.len);
 
2053
        }
 
2054
        TIMEFINISH(cipherInfo->optime, 1.0);
 
2055
    }
 
2056
    PORT_Free(dummyOut);
 
2057
    return rv;
 
2058
}
 
2059
 
 
2060
SECStatus
 
2061
cipherFinish(bltestCipherInfo *cipherInfo)
 
2062
{
 
2063
    switch (cipherInfo->mode) {
 
2064
    case bltestDES_ECB:
 
2065
    case bltestDES_CBC:
 
2066
    case bltestDES_EDE_ECB:
 
2067
    case bltestDES_EDE_CBC:
 
2068
        DES_DestroyContext((DESContext *)cipherInfo->cx, PR_TRUE);
 
2069
        break;
 
2070
    case bltestAES_ECB:
 
2071
    case bltestAES_CBC:
 
2072
        AES_DestroyContext((AESContext *)cipherInfo->cx, PR_TRUE);
 
2073
        break;
 
2074
    case bltestRC2_ECB:
 
2075
    case bltestRC2_CBC:
 
2076
        RC2_DestroyContext((RC2Context *)cipherInfo->cx, PR_TRUE);
 
2077
        break;
 
2078
    case bltestRC4:
 
2079
        RC4_DestroyContext((RC4Context *)cipherInfo->cx, PR_TRUE);
 
2080
        break;
 
2081
#if NSS_SOFTOKEN_DOES_RC5
 
2082
    case bltestRC5_ECB:
 
2083
    case bltestRC5_CBC:
 
2084
        RC5_DestroyContext((RC5Context *)cipherInfo->cx, PR_TRUE);
 
2085
        break;
 
2086
#endif
 
2087
    case bltestRSA: /* keys are alloc'ed within cipherInfo's arena, */
 
2088
    case bltestDSA: /* will be freed with it. */
 
2089
#ifdef NSS_ENABLE_ECC
 
2090
    case bltestECDSA:
 
2091
#endif
 
2092
    case bltestMD2: /* hash contexts are ephemeral */
 
2093
    case bltestMD5:
 
2094
    case bltestSHA1:
 
2095
    case bltestSHA256:
 
2096
    case bltestSHA384:
 
2097
    case bltestSHA512:
 
2098
        return SECSuccess;
 
2099
        break;
 
2100
    default:
 
2101
        return SECFailure;
 
2102
    }
 
2103
    return SECSuccess;
 
2104
}
 
2105
 
 
2106
void
 
2107
print_exponent(SECItem *exp)
 
2108
{
 
2109
    int i;
 
2110
    int e = 0;
 
2111
    if (exp->len <= 4) {
 
2112
        for (i=exp->len; i >=0; --i) e |= exp->data[exp->len-i] << 8*(i-1);
 
2113
        fprintf(stdout, "%12d", e);
 
2114
    } else {
 
2115
        e = 8*exp->len;
 
2116
        fprintf(stdout, "~2**%-8d", e);
 
2117
    }
 
2118
}
 
2119
 
 
2120
void
 
2121
dump_performance_info(bltestCipherInfo *info, PRBool encrypt, PRBool cxonly)
 
2122
{
 
2123
    PRBool td = PR_TRUE;
 
2124
    fprintf(stdout, "#%9s", "mode");
 
2125
    fprintf(stdout, "%12s", "in");
 
2126
print_td:
 
2127
    switch (info->mode) {
 
2128
    case bltestDES_ECB:
 
2129
    case bltestDES_CBC:
 
2130
    case bltestDES_EDE_ECB:
 
2131
    case bltestDES_EDE_CBC:
 
2132
    case bltestAES_ECB:
 
2133
    case bltestAES_CBC:
 
2134
    case bltestRC2_ECB:
 
2135
    case bltestRC2_CBC:
 
2136
    case bltestRC4:
 
2137
        if (td)
 
2138
            fprintf(stdout, "%8s", "symmkey");
 
2139
        else
 
2140
            fprintf(stdout, "%8d", 8*info->params.sk.key.buf.len);
 
2141
        break;
 
2142
#if NSS_SOFTOKEN_DOES_RC5
 
2143
    case bltestRC5_ECB:
 
2144
    case bltestRC5_CBC:
 
2145
        if (info->params.sk.key.buf.len > 0)
 
2146
            printf("symmetric key(bytes)=%d,", info->params.sk.key.buf.len);
 
2147
        if (info->rounds > 0)
 
2148
            printf("rounds=%d,", info->params.rc5.rounds);
 
2149
        if (info->wordsize > 0)
 
2150
            printf("wordsize(bytes)=%d,", info->params.rc5.wordsize);
 
2151
        break;
 
2152
#endif
 
2153
    case bltestRSA:
 
2154
        if (td) {
 
2155
            fprintf(stdout, "%8s", "rsa_mod");
 
2156
            fprintf(stdout, "%12s", "rsa_pe");
 
2157
        } else {
 
2158
            fprintf(stdout, "%8d", info->params.rsa.keysizeInBits);
 
2159
            print_exponent(&info->params.rsa.rsakey->publicExponent);
 
2160
        }
 
2161
        break;
 
2162
    case bltestDSA:
 
2163
        if (td)
 
2164
            fprintf(stdout, "%8s", "pqg_mod");
 
2165
        else
 
2166
            fprintf(stdout, "%8d", PQG_INDEX_TO_PBITS(info->params.dsa.j));
 
2167
        break;
 
2168
#ifdef NSS_ENABLE_ECC
 
2169
    case bltestECDSA:
 
2170
        if (td)
 
2171
            fprintf(stdout, "%12s", "ec_curve");
 
2172
        else
 
2173
            fprintf(stdout, "%12s", ecCurve_map[info->params.ecdsa.eckey->ecParams.name]->text);
 
2174
        break;
 
2175
#endif
 
2176
    case bltestMD2:
 
2177
    case bltestMD5:
 
2178
    case bltestSHA1:
 
2179
    case bltestSHA256:
 
2180
    case bltestSHA384:
 
2181
    case bltestSHA512:
 
2182
    default:
 
2183
        break;
 
2184
    }
 
2185
    if (!td) {
 
2186
        fprintf(stdout, "%8d", info->repetitions);
 
2187
        fprintf(stdout, "%8d", info->cxreps);
 
2188
        fprintf(stdout, "%12.3f", info->cxtime);
 
2189
        fprintf(stdout, "%12.3f", info->optime);
 
2190
        fprintf(stdout, "\n");
 
2191
        return;
 
2192
    }
 
2193
 
 
2194
    fprintf(stdout, "%8s", "opreps");
 
2195
    fprintf(stdout, "%8s", "cxreps");
 
2196
    fprintf(stdout, "%12s", "context");
 
2197
    fprintf(stdout, "%12s", "op");
 
2198
    fprintf(stdout, "\n");
 
2199
    fprintf(stdout, "%8s", mode_strings[info->mode]);
 
2200
    fprintf(stdout, "_%c", (cxonly) ? 'c' : (encrypt) ? 'e' : 'd');
 
2201
    fprintf(stdout, "%12d", info->input.buf.len * info->repetitions);
 
2202
 
 
2203
    td = !td;
 
2204
    goto print_td;
 
2205
}
 
2206
 
 
2207
void
 
2208
printmodes()
 
2209
{
 
2210
    bltestCipherMode mode;
 
2211
    int nummodes = sizeof(mode_strings) / sizeof(char *);
 
2212
    fprintf(stderr, "%s: Available modes (specify with -m):\n", progName);
 
2213
    for (mode=0; mode<nummodes; mode++)
 
2214
        fprintf(stderr, "%s\n", mode_strings[mode]);
 
2215
}
 
2216
 
 
2217
bltestCipherMode
 
2218
get_mode(const char *modestring)
 
2219
{
 
2220
    bltestCipherMode mode;
 
2221
    int nummodes = sizeof(mode_strings) / sizeof(char *);
 
2222
    for (mode=0; mode<nummodes; mode++)
 
2223
        if (PL_strcmp(modestring, mode_strings[mode]) == 0)
 
2224
            return mode;
 
2225
    fprintf(stderr, "%s: invalid mode: %s\n", progName, modestring);
 
2226
    return bltestINVALID;
 
2227
}
 
2228
 
 
2229
void
 
2230
load_file_data(PRArenaPool *arena, bltestIO *data,
 
2231
               char *fn, bltestIOMode ioMode)
 
2232
{
 
2233
    PRFileDesc *file;
 
2234
    data->mode = ioMode;
 
2235
    data->file = NULL; /* don't use -- not saving anything */
 
2236
    data->pBuf.data = NULL;
 
2237
    data->pBuf.len = 0;
 
2238
    file = PR_Open(fn, PR_RDONLY, 00660);
 
2239
    if (file)
 
2240
        setupIO(arena, data, file, NULL, 0);
 
2241
}
 
2242
 
 
2243
void
 
2244
get_params(PRArenaPool *arena, bltestParams *params, 
 
2245
           bltestCipherMode mode, int j)
 
2246
{
 
2247
    char filename[256];
 
2248
    char *modestr = mode_strings[mode];
 
2249
#if NSS_SOFTOKEN_DOES_RC5
 
2250
    FILE *file;
 
2251
    char *mark, *param, *val;
 
2252
    int index = 0;
 
2253
#endif
 
2254
    switch (mode) {
 
2255
    case bltestDES_CBC:
 
2256
    case bltestDES_EDE_CBC:
 
2257
    case bltestRC2_CBC:
 
2258
    case bltestAES_CBC:
 
2259
        sprintf(filename, "%s/tests/%s/%s%d", testdir, modestr, "iv", j);
 
2260
        load_file_data(arena, &params->sk.iv, filename, bltestBinary);
 
2261
    case bltestDES_ECB:
 
2262
    case bltestDES_EDE_ECB:
 
2263
    case bltestRC2_ECB:
 
2264
    case bltestRC4:
 
2265
    case bltestAES_ECB:
 
2266
        sprintf(filename, "%s/tests/%s/%s%d", testdir, modestr, "key", j);
 
2267
        load_file_data(arena, &params->sk.key, filename, bltestBinary);
 
2268
        break;
 
2269
#if NSS_SOFTOKEN_DOES_RC5
 
2270
    case bltestRC5_ECB:
 
2271
    case bltestRC5_CBC:
 
2272
        sprintf(filename, "%s/tests/%s/%s%d", testdir, modestr, "iv", j);
 
2273
        load_file_data(arena, &params->sk.iv, filename, bltestBinary);
 
2274
        sprintf(filename, "%s/tests/%s/%s%d", testdir, modestr, "key", j);
 
2275
        load_file_data(arena, &params->sk.key, filename, bltestBinary);
 
2276
            sprintf(filename, "%s/tests/%s/%s%d", testdir, modestr,
 
2277
                              "params", j);
 
2278
        file = fopen(filename, "r");
 
2279
        if (!file) return;
 
2280
        param = malloc(100);
 
2281
        len = fread(param, 1, 100, file);
 
2282
        while (index < len) {
 
2283
            mark = PL_strchr(param, '=');
 
2284
            *mark = '\0';
 
2285
            val = mark + 1;
 
2286
            mark = PL_strchr(val, '\n');
 
2287
            *mark = '\0';
 
2288
            if (PL_strcmp(param, "rounds") == 0) {
 
2289
                params->rc5.rounds = atoi(val);
 
2290
            } else if (PL_strcmp(param, "wordsize") == 0) {
 
2291
                params->rc5.wordsize = atoi(val);
 
2292
            }
 
2293
            index += PL_strlen(param) + PL_strlen(val) + 2;
 
2294
            param = mark + 1;
 
2295
        }
 
2296
        break;
 
2297
#endif
 
2298
    case bltestRSA:
 
2299
        sprintf(filename, "%s/tests/%s/%s%d", testdir, modestr, "key", j);
 
2300
        load_file_data(arena, &params->rsa.key, filename, bltestBase64Encoded);
 
2301
        params->rsa.rsakey = rsakey_from_filedata(&params->key.buf);
 
2302
        break;
 
2303
    case bltestDSA:
 
2304
        sprintf(filename, "%s/tests/%s/%s%d", testdir, modestr, "key", j);
 
2305
        load_file_data(arena, &params->dsa.key, filename, bltestBase64Encoded);
 
2306
        params->dsa.dsakey = dsakey_from_filedata(&params->key.buf);
 
2307
        sprintf(filename, "%s/tests/%s/%s%d", testdir, modestr, "pqg", j);
 
2308
        load_file_data(arena, &params->dsa.pqgdata, filename,
 
2309
                       bltestBase64Encoded);
 
2310
        params->dsa.pqg = pqg_from_filedata(&params->dsa.pqgdata.buf);
 
2311
        sprintf(filename, "%s/tests/%s/%s%d", testdir, modestr, "keyseed", j);
 
2312
        load_file_data(arena, &params->dsa.keyseed, filename, 
 
2313
                       bltestBase64Encoded);
 
2314
        sprintf(filename, "%s/tests/%s/%s%d", testdir, modestr, "sigseed", j);
 
2315
        load_file_data(arena, &params->dsa.sigseed, filename, 
 
2316
                       bltestBase64Encoded);
 
2317
        sprintf(filename, "%s/tests/%s/%s%d", testdir, modestr, "ciphertext",j);
 
2318
        load_file_data(arena, &params->dsa.sig, filename, bltestBase64Encoded);
 
2319
        break;
 
2320
#ifdef NSS_ENABLE_ECC
 
2321
    case bltestECDSA:
 
2322
        sprintf(filename, "%s/tests/%s/%s%d", testdir, modestr, "key", j);
 
2323
        load_file_data(arena, &params->ecdsa.key, filename, bltestBase64Encoded);
 
2324
        params->ecdsa.eckey = eckey_from_filedata(&params->key.buf);
 
2325
        sprintf(filename, "%s/tests/%s/%s%d", testdir, modestr, "sigseed", j);
 
2326
        load_file_data(arena, &params->ecdsa.sigseed, filename, 
 
2327
                       bltestBase64Encoded);
 
2328
        sprintf(filename, "%s/tests/%s/%s%d", testdir, modestr, "ciphertext",j);
 
2329
        load_file_data(arena, &params->ecdsa.sig, filename, bltestBase64Encoded);
 
2330
        break;
 
2331
#endif
 
2332
    case bltestMD2:
 
2333
    case bltestMD5:
 
2334
    case bltestSHA1:
 
2335
    case bltestSHA256:
 
2336
    case bltestSHA384:
 
2337
    case bltestSHA512:
 
2338
        /*params->hash.restart = PR_TRUE;*/
 
2339
        params->hash.restart = PR_FALSE;
 
2340
        break;
 
2341
    default:
 
2342
        break;
 
2343
    }
 
2344
}
 
2345
 
 
2346
SECStatus
 
2347
verify_self_test(bltestIO *result, bltestIO *cmp, bltestCipherMode mode,
 
2348
                 PRBool forward, SECStatus sigstatus)
 
2349
{
 
2350
    int res;
 
2351
    char *modestr = mode_strings[mode];
 
2352
    res = SECITEM_CompareItem(&result->pBuf, &cmp->buf);
 
2353
    if (is_sigCipher(mode)) {
 
2354
        if (forward) {
 
2355
            if (res == 0) {
 
2356
                printf("Signature self-test for %s passed.\n", modestr);
 
2357
            } else {
 
2358
                printf("Signature self-test for %s failed!\n", modestr);
 
2359
            }
 
2360
        } else {
 
2361
            if (sigstatus == SECSuccess) {
 
2362
                printf("Verification self-test for %s passed.\n", modestr);
 
2363
            } else {
 
2364
                printf("Verification self-test for %s failed!\n", modestr);
 
2365
            }
 
2366
        }
 
2367
        return sigstatus;
 
2368
    } else if (is_hashCipher(mode)) {
 
2369
        if (res == 0) {
 
2370
            printf("Hash self-test for %s passed.\n", modestr);
 
2371
        } else {
 
2372
            printf("Hash self-test for %s failed!\n", modestr);
 
2373
        }
 
2374
    } else {
 
2375
        if (forward) {
 
2376
            if (res == 0) {
 
2377
                printf("Encryption self-test for %s passed.\n", modestr);
 
2378
            } else {
 
2379
                printf("Encryption self-test for %s failed!\n", modestr);
 
2380
            }
 
2381
        } else {
 
2382
            if (res == 0) {
 
2383
                printf("Decryption self-test for %s passed.\n", modestr);
 
2384
            } else {
 
2385
                printf("Decryption self-test for %s failed!\n", modestr);
 
2386
            }
 
2387
        }
 
2388
    }
 
2389
    return (res != 0);
 
2390
}
 
2391
 
 
2392
static SECStatus
 
2393
blapi_selftest(bltestCipherMode *modes, int numModes, int inoff, int outoff,
 
2394
               PRBool encrypt, PRBool decrypt)
 
2395
{
 
2396
    bltestCipherInfo cipherInfo;
 
2397
    bltestIO pt, ct;
 
2398
    bltestCipherMode mode;
 
2399
    bltestParams *params;
 
2400
    int i, j, nummodes, numtests;
 
2401
    char *modestr;
 
2402
    char filename[256];
 
2403
    PRFileDesc *file;
 
2404
    PRArenaPool *arena;
 
2405
    SECItem item;
 
2406
    PRBool finished;
 
2407
    SECStatus rv = SECSuccess, srv;
 
2408
 
 
2409
    PORT_Memset(&cipherInfo, 0, sizeof(cipherInfo));
 
2410
    arena = PORT_NewArena(BLTEST_DEFAULT_CHUNKSIZE);
 
2411
    cipherInfo.arena = arena;
 
2412
 
 
2413
    finished = PR_FALSE;
 
2414
    nummodes = (numModes == 0) ? NUMMODES : numModes;
 
2415
    for (i=0; i < nummodes && !finished; i++) {
 
2416
        if (i == bltestRC5_ECB || i == bltestRC5_CBC) continue;
 
2417
        if (numModes > 0)
 
2418
            mode = modes[i];
 
2419
        else
 
2420
            mode = i;
 
2421
        if (mode == bltestINVALID) {
 
2422
            fprintf(stderr, "%s: Skipping invalid mode.\n",progName);
 
2423
            continue;
 
2424
        }
 
2425
        modestr = mode_strings[mode];
 
2426
        cipherInfo.mode = mode;
 
2427
        params = &cipherInfo.params;
 
2428
#ifdef TRACK_BLTEST_BUG
 
2429
        if (mode == bltestRSA) {
 
2430
            fprintf(stderr, "[%s] Self-Testing RSA\n", __bltDBG);
 
2431
        }
 
2432
#endif
 
2433
        /* get the number of tests in the directory */
 
2434
        sprintf(filename, "%s/tests/%s/%s", testdir, modestr, "numtests");
 
2435
        file = PR_Open(filename, PR_RDONLY, 00660);
 
2436
        if (!file) {
 
2437
            fprintf(stderr, "%s: File %s does not exist.\n", progName,filename);
 
2438
            return SECFailure;
 
2439
        }
 
2440
        rv = SECU_FileToItem(&item, file);
 
2441
#ifdef TRACK_BLTEST_BUG
 
2442
        if (mode == bltestRSA) {
 
2443
            fprintf(stderr, "[%s] Loaded data from %s\n", __bltDBG, filename);
 
2444
        }
 
2445
#endif
 
2446
        PR_Close(file);
 
2447
        /* loop over the tests in the directory */
 
2448
        numtests = (int) (item.data[0] - '0');
 
2449
        for (j=1; j<item.len - 1; j++) {
 
2450
            numtests *= 10;
 
2451
            numtests += (int) (item.data[j] - '0');
 
2452
        }
 
2453
        for (j=0; j<numtests; j++) {
 
2454
#ifdef TRACK_BLTEST_BUG
 
2455
            if (mode == bltestRSA) {
 
2456
                fprintf(stderr, "[%s] Executing self-test #%d\n", __bltDBG, j);
 
2457
            }
 
2458
#endif
 
2459
            sprintf(filename, "%s/tests/%s/%s%d", testdir, modestr,
 
2460
                              "plaintext", j);
 
2461
            load_file_data(arena, &pt, filename, 
 
2462
#ifdef NSS_ENABLE_ECC
 
2463
                           ((mode == bltestDSA) || (mode == bltestECDSA))
 
2464
#else
 
2465
                           (mode == bltestDSA)
 
2466
#endif
 
2467
                           ? bltestBase64Encoded : bltestBinary);
 
2468
            sprintf(filename, "%s/tests/%s/%s%d", testdir, modestr,
 
2469
                              "ciphertext", j);
 
2470
            load_file_data(arena, &ct, filename, bltestBase64Encoded);
 
2471
#ifdef TRACK_BLTEST_BUG
 
2472
            if (mode == bltestRSA) {
 
2473
                fprintf(stderr, "[%s] Loaded data for  self-test #%d\n", __bltDBG, j);
 
2474
            }
 
2475
#endif
 
2476
            get_params(arena, params, mode, j);
 
2477
#ifdef TRACK_BLTEST_BUG
 
2478
            if (mode == bltestRSA) {
 
2479
                fprintf(stderr, "[%s] Got parameters for #%d\n", __bltDBG, j);
 
2480
            }
 
2481
#endif
 
2482
            /* Forward Operation (Encrypt/Sign/Hash)
 
2483
            ** Align the input buffer (plaintext) according to request
 
2484
            ** then perform operation and compare to ciphertext
 
2485
            */
 
2486
            /* XXX for now */
 
2487
            rv = SECSuccess;
 
2488
            if (encrypt) {
 
2489
                bltestCopyIO(arena, &cipherInfo.input, &pt);
 
2490
                misalignBuffer(arena, &cipherInfo.input, inoff);
 
2491
                memset(&cipherInfo.output.buf, 0, sizeof cipherInfo.output.buf);
 
2492
                rv |= cipherInit(&cipherInfo, PR_TRUE);
 
2493
                misalignBuffer(arena, &cipherInfo.output, outoff);
 
2494
#ifdef TRACK_BLTEST_BUG
 
2495
                if (mode == bltestRSA) {
 
2496
                    fprintf(stderr, "[%s] Inited cipher context and buffers for #%d\n", __bltDBG, j);
 
2497
                }
 
2498
#endif
 
2499
                rv |= cipherDoOp(&cipherInfo);
 
2500
#ifdef TRACK_BLTEST_BUG
 
2501
                if (mode == bltestRSA) {
 
2502
                    fprintf(stderr, "[%s] Performed encrypt for #%d\n", __bltDBG, j);
 
2503
                }
 
2504
#endif
 
2505
                rv |= cipherFinish(&cipherInfo);
 
2506
#ifdef TRACK_BLTEST_BUG
 
2507
                if (mode == bltestRSA) {
 
2508
                    fprintf(stderr, "[%s] Finished encrypt for #%d\n", __bltDBG, j);
 
2509
                }
 
2510
#endif
 
2511
                rv |= verify_self_test(&cipherInfo.output, 
 
2512
                                       &ct, mode, PR_TRUE, 0);
 
2513
#ifdef TRACK_BLTEST_BUG
 
2514
                if (mode == bltestRSA) {
 
2515
                    fprintf(stderr, "[%s] Verified self-test for #%d\n", __bltDBG, j);
 
2516
                }
 
2517
#endif
 
2518
                /* If testing hash, only one op to test */
 
2519
                if (is_hashCipher(mode))
 
2520
                    continue;
 
2521
                /*if (rv) return rv;*/
 
2522
            }
 
2523
            if (!decrypt)
 
2524
                continue;
 
2525
            /* XXX for now */
 
2526
            rv = SECSuccess;
 
2527
            /* Reverse Operation (Decrypt/Verify)
 
2528
            ** Align the input buffer (ciphertext) according to request
 
2529
            ** then perform operation and compare to plaintext
 
2530
            */
 
2531
#ifdef NSS_ENABLE_ECC
 
2532
            if ((mode != bltestDSA) && (mode != bltestECDSA))
 
2533
#else
 
2534
            if (mode != bltestDSA)
 
2535
#endif
 
2536
                bltestCopyIO(arena, &cipherInfo.input, &ct);
 
2537
            else
 
2538
                bltestCopyIO(arena, &cipherInfo.input, &pt);
 
2539
            misalignBuffer(arena, &cipherInfo.input, inoff);
 
2540
            memset(&cipherInfo.output.buf, 0, sizeof cipherInfo.output.buf);
 
2541
            rv |= cipherInit(&cipherInfo, PR_FALSE);
 
2542
            misalignBuffer(arena, &cipherInfo.output, outoff);
 
2543
#ifdef TRACK_BLTEST_BUG
 
2544
            if (mode == bltestRSA) {
 
2545
                fprintf(stderr, "[%s] Inited cipher context and buffers for #%d\n", __bltDBG, j);
 
2546
            }
 
2547
#endif
 
2548
            srv = SECSuccess;
 
2549
            srv |= cipherDoOp(&cipherInfo);
 
2550
#ifdef TRACK_BLTEST_BUG
 
2551
            if (mode == bltestRSA) {
 
2552
                fprintf(stderr, "[%s] Performed decrypt for #%d\n", __bltDBG, j);
 
2553
            }
 
2554
#endif
 
2555
            rv |= cipherFinish(&cipherInfo);
 
2556
#ifdef TRACK_BLTEST_BUG
 
2557
            if (mode == bltestRSA) {
 
2558
                fprintf(stderr, "[%s] Finished decrypt for #%d\n", __bltDBG, j);
 
2559
            }
 
2560
#endif
 
2561
            rv |= verify_self_test(&cipherInfo.output, 
 
2562
                                   &pt, mode, PR_FALSE, srv);
 
2563
#ifdef TRACK_BLTEST_BUG
 
2564
            if (mode == bltestRSA) {
 
2565
                fprintf(stderr, "[%s] Verified self-test for #%d\n", __bltDBG, j);
 
2566
            }
 
2567
#endif
 
2568
            /*if (rv) return rv;*/
 
2569
        }
 
2570
    }
 
2571
    return rv;
 
2572
}
 
2573
 
 
2574
SECStatus
 
2575
dump_file(bltestCipherMode mode, char *filename)
 
2576
{
 
2577
    bltestIO keydata;
 
2578
    PRArenaPool *arena = NULL;
 
2579
    arena = PORT_NewArena(BLTEST_DEFAULT_CHUNKSIZE);
 
2580
    if (mode == bltestRSA) {
 
2581
        RSAPrivateKey *key;
 
2582
        load_file_data(arena, &keydata, filename, bltestBase64Encoded);
 
2583
        key = rsakey_from_filedata(&keydata.buf);
 
2584
        dump_rsakey(key);
 
2585
    } else if (mode == bltestDSA) {
 
2586
#if 0
 
2587
        PQGParams *pqg;
 
2588
        get_file_data(filename, &item, PR_TRUE);
 
2589
        pqg = pqg_from_filedata(&item);
 
2590
        dump_pqg(pqg);
 
2591
#endif
 
2592
        DSAPrivateKey *key;
 
2593
        load_file_data(arena, &keydata, filename, bltestBase64Encoded);
 
2594
        key = dsakey_from_filedata(&keydata.buf);
 
2595
        dump_dsakey(key);
 
2596
#ifdef NSS_ENABLE_ECC
 
2597
    } else if (mode == bltestECDSA) {
 
2598
        ECPrivateKey *key;
 
2599
        load_file_data(arena, &keydata, filename, bltestBase64Encoded);
 
2600
        key = eckey_from_filedata(&keydata.buf);
 
2601
        dump_eckey(key);
 
2602
#endif
 
2603
    }
 
2604
    PORT_FreeArena(arena, PR_FALSE);
 
2605
    return SECFailure;
 
2606
}
 
2607
 
 
2608
/* bltest commands */
 
2609
enum {
 
2610
    cmd_Decrypt = 0,
 
2611
    cmd_Encrypt,
 
2612
    cmd_FIPS,
 
2613
    cmd_Hash,
 
2614
    cmd_Nonce,
 
2615
    cmd_Dump,
 
2616
    cmd_Sign,
 
2617
    cmd_SelfTest,
 
2618
    cmd_Verify
 
2619
};
 
2620
 
 
2621
/* bltest options */
 
2622
enum {
 
2623
    opt_B64 = 0,
 
2624
    opt_BufSize,
 
2625
    opt_Restart,
 
2626
    opt_SelfTestDir,
 
2627
    opt_Exponent,
 
2628
    opt_SigFile,
 
2629
    opt_KeySize,
 
2630
    opt_Hex,
 
2631
    opt_Input,
 
2632
    opt_PQGFile,
 
2633
    opt_Key,
 
2634
    opt_HexWSpc,
 
2635
    opt_Mode,
 
2636
#ifdef NSS_ENABLE_ECC
 
2637
    opt_CurveName,
 
2638
#endif
 
2639
    opt_Output,
 
2640
    opt_Repetitions,
 
2641
    opt_ZeroBuf,
 
2642
    opt_Rounds,
 
2643
    opt_Seed,
 
2644
    opt_SigSeedFile,
 
2645
    opt_CXReps,
 
2646
    opt_IV,
 
2647
    opt_WordSize,
 
2648
    opt_UseSeed,
 
2649
    opt_UseSigSeed,
 
2650
    opt_SeedFile,
 
2651
    opt_InputOffset,
 
2652
    opt_OutputOffset,
 
2653
    opt_MonteCarlo,
 
2654
    opt_CmdLine
 
2655
};
 
2656
 
 
2657
static secuCommandFlag bltest_commands[] =
 
2658
{
 
2659
    { /* cmd_Decrypt    */ 'D', PR_FALSE, 0, PR_FALSE },
 
2660
    { /* cmd_Encrypt    */ 'E', PR_FALSE, 0, PR_FALSE },
 
2661
    { /* cmd_FIPS       */ 'F', PR_FALSE, 0, PR_FALSE },
 
2662
    { /* cmd_Hash       */ 'H', PR_FALSE, 0, PR_FALSE },
 
2663
    { /* cmd_Nonce      */ 'N', PR_FALSE, 0, PR_FALSE },
 
2664
    { /* cmd_Dump       */ 'P', PR_FALSE, 0, PR_FALSE },
 
2665
    { /* cmd_Sign       */ 'S', PR_FALSE, 0, PR_FALSE },
 
2666
    { /* cmd_SelfTest   */ 'T', PR_FALSE, 0, PR_FALSE },
 
2667
    { /* cmd_Verify     */ 'V', PR_FALSE, 0, PR_FALSE }
 
2668
};
 
2669
 
 
2670
static secuCommandFlag bltest_options[] =
 
2671
{
 
2672
    { /* opt_B64          */ 'a', PR_FALSE, 0, PR_FALSE },
 
2673
    { /* opt_BufSize      */ 'b', PR_TRUE,  0, PR_FALSE },
 
2674
    { /* opt_Restart      */ 'c', PR_FALSE, 0, PR_FALSE },
 
2675
    { /* opt_SelfTestDir  */ 'd', PR_TRUE,  0, PR_FALSE },
 
2676
    { /* opt_Exponent     */ 'e', PR_TRUE,  0, PR_FALSE },
 
2677
    { /* opt_SigFile      */ 'f', PR_TRUE,  0, PR_FALSE },
 
2678
    { /* opt_KeySize      */ 'g', PR_TRUE,  0, PR_FALSE },
 
2679
    { /* opt_Hex          */ 'h', PR_FALSE, 0, PR_FALSE },
 
2680
    { /* opt_Input        */ 'i', PR_TRUE,  0, PR_FALSE },
 
2681
    { /* opt_PQGFile      */ 'j', PR_TRUE,  0, PR_FALSE },
 
2682
    { /* opt_Key          */ 'k', PR_TRUE,  0, PR_FALSE },
 
2683
    { /* opt_HexWSpc      */ 'l', PR_FALSE, 0, PR_FALSE },
 
2684
    { /* opt_Mode         */ 'm', PR_TRUE,  0, PR_FALSE },
 
2685
#ifdef NSS_ENABLE_ECC
 
2686
    { /* opt_CurveName    */ 'n', PR_TRUE,  0, PR_FALSE },
 
2687
#endif
 
2688
    { /* opt_Output       */ 'o', PR_TRUE,  0, PR_FALSE },
 
2689
    { /* opt_Repetitions  */ 'p', PR_TRUE,  0, PR_FALSE },
 
2690
    { /* opt_ZeroBuf      */ 'q', PR_FALSE, 0, PR_FALSE },
 
2691
    { /* opt_Rounds       */ 'r', PR_TRUE,  0, PR_FALSE },
 
2692
    { /* opt_Seed         */ 's', PR_TRUE,  0, PR_FALSE },
 
2693
    { /* opt_SigSeedFile  */ 't', PR_TRUE,  0, PR_FALSE },
 
2694
    { /* opt_CXReps       */ 'u', PR_TRUE,  0, PR_FALSE },
 
2695
    { /* opt_IV           */ 'v', PR_TRUE,  0, PR_FALSE },
 
2696
    { /* opt_WordSize     */ 'w', PR_TRUE,  0, PR_FALSE },
 
2697
    { /* opt_UseSeed      */ 'x', PR_FALSE, 0, PR_FALSE },
 
2698
    { /* opt_UseSigSeed   */ 'y', PR_FALSE, 0, PR_FALSE },
 
2699
    { /* opt_SeedFile     */ 'z', PR_FALSE, 0, PR_FALSE },
 
2700
    { /* opt_InputOffset  */ '1', PR_TRUE,  0, PR_FALSE },
 
2701
    { /* opt_OutputOffset */ '2', PR_TRUE,  0, PR_FALSE },
 
2702
    { /* opt_MonteCarlo   */ '3', PR_FALSE, 0, PR_FALSE },
 
2703
    { /* opt_CmdLine      */ '-', PR_FALSE, 0, PR_FALSE }
 
2704
};
 
2705
 
 
2706
int main(int argc, char **argv)
 
2707
{
 
2708
    char *infileName, *outfileName, *keyfileName, *ivfileName;
 
2709
    SECStatus rv;
 
2710
 
 
2711
    bltestCipherInfo     cipherInfo;
 
2712
    bltestParams        *params;
 
2713
    PRFileDesc          *file, *infile, *outfile;
 
2714
    char                *instr = NULL;
 
2715
    PRArenaPool         *arena;
 
2716
    bltestIOMode         ioMode;
 
2717
    int                  keysize, bufsize, exponent;
 
2718
#ifdef NSS_ENABLE_ECC
 
2719
    char                *curveName = NULL;
 
2720
#endif
 
2721
    int                  i, commandsEntered;
 
2722
    int                  inoff, outoff;
 
2723
 
 
2724
    secuCommand bltest;
 
2725
    bltest.numCommands = sizeof(bltest_commands) / sizeof(secuCommandFlag);
 
2726
    bltest.numOptions = sizeof(bltest_options) / sizeof(secuCommandFlag);
 
2727
    bltest.commands = bltest_commands;
 
2728
    bltest.options = bltest_options;
 
2729
 
 
2730
    progName = strrchr(argv[0], '/');
 
2731
    if (!progName) 
 
2732
        progName = strrchr(argv[0], '\\');
 
2733
    progName = progName ? progName+1 : argv[0];
 
2734
 
 
2735
    rv = RNG_RNGInit();
 
2736
    if (rv != SECSuccess) {
 
2737
        SECU_PrintPRandOSError(progName);
 
2738
        return -1;
 
2739
    }
 
2740
    RNG_SystemInfoForRNG();
 
2741
 
 
2742
    rv = SECU_ParseCommandLine(argc, argv, progName, &bltest);
 
2743
 
 
2744
    PORT_Memset(&cipherInfo, 0, sizeof(cipherInfo));
 
2745
    arena = PORT_NewArena(BLTEST_DEFAULT_CHUNKSIZE);
 
2746
    cipherInfo.arena = arena;
 
2747
    params = &cipherInfo.params;
 
2748
    /* set some defaults */
 
2749
    infileName = outfileName = keyfileName = ivfileName = NULL;
 
2750
 
 
2751
    /* Check the number of commands entered on the command line. */
 
2752
    commandsEntered = 0;
 
2753
    for (i=0; i<bltest.numCommands; i++)
 
2754
        if (bltest.commands[i].activated)
 
2755
            commandsEntered++;
 
2756
 
 
2757
    if (commandsEntered > 1 &&
 
2758
        !(commandsEntered == 2 && bltest.commands[cmd_SelfTest].activated)) {
 
2759
        fprintf(stderr, "%s: one command at a time!\n", progName);
 
2760
        Usage();
 
2761
    }
 
2762
    if (commandsEntered == 0) {
 
2763
        fprintf(stderr, "%s: you must enter a command!\n", progName);
 
2764
        Usage();
 
2765
    }
 
2766
 
 
2767
    if (bltest.commands[cmd_Sign].activated)
 
2768
        bltest.commands[cmd_Encrypt].activated = PR_TRUE;
 
2769
    if (bltest.commands[cmd_Verify].activated)
 
2770
        bltest.commands[cmd_Decrypt].activated = PR_TRUE;
 
2771
    if (bltest.commands[cmd_Hash].activated)
 
2772
        bltest.commands[cmd_Encrypt].activated = PR_TRUE;
 
2773
 
 
2774
    inoff = outoff = 0;
 
2775
    if (bltest.options[opt_InputOffset].activated)
 
2776
        inoff = PORT_Atoi(bltest.options[opt_InputOffset].arg);
 
2777
    if (bltest.options[opt_OutputOffset].activated)
 
2778
        outoff = PORT_Atoi(bltest.options[opt_OutputOffset].arg);
 
2779
 
 
2780
    testdir = (bltest.options[opt_SelfTestDir].activated) ? 
 
2781
                 strdup(bltest.options[opt_SelfTestDir].arg) : ".";
 
2782
 
 
2783
    /*
 
2784
     * Handle three simple cases first
 
2785
     */
 
2786
 
 
2787
    /* Do BLAPI self-test */
 
2788
    if (bltest.commands[cmd_SelfTest].activated) {
 
2789
        PRBool encrypt = PR_TRUE, decrypt = PR_TRUE;
 
2790
        /* user may specified a set of ciphers to test.  parse them. */
 
2791
        bltestCipherMode modesToTest[NUMMODES];
 
2792
        int numModesToTest = 0;
 
2793
        char *tok, *str;
 
2794
        str = bltest.options[opt_Mode].arg;
 
2795
        while (str) {
 
2796
            tok = strchr(str, ',');
 
2797
            if (tok) *tok = '\0';
 
2798
            modesToTest[numModesToTest++] = get_mode(str);
 
2799
            if (tok) {
 
2800
                *tok = ',';
 
2801
                str = tok + 1;
 
2802
            } else {
 
2803
                break;
 
2804
            }
 
2805
        }
 
2806
        if (bltest.commands[cmd_Decrypt].activated &&
 
2807
            !bltest.commands[cmd_Encrypt].activated)
 
2808
            encrypt = PR_FALSE;
 
2809
        if (bltest.commands[cmd_Encrypt].activated &&
 
2810
            !bltest.commands[cmd_Decrypt].activated)
 
2811
            decrypt = PR_FALSE;
 
2812
        return blapi_selftest(modesToTest, numModesToTest, inoff, outoff,
 
2813
                              encrypt, decrypt);
 
2814
    }
 
2815
 
 
2816
    /* Do FIPS self-test */
 
2817
    if (bltest.commands[cmd_FIPS].activated) {
 
2818
        CK_RV ckrv = pk11_fipsPowerUpSelfTest();
 
2819
        fprintf(stdout, "CK_RV: %ld.\n", ckrv);
 
2820
        return 0;
 
2821
    }
 
2822
 
 
2823
    /*
 
2824
     * Check command line arguments for Encrypt/Decrypt/Hash/Sign/Verify
 
2825
     */
 
2826
 
 
2827
    if ((bltest.commands[cmd_Decrypt].activated ||
 
2828
         bltest.commands[cmd_Verify].activated) &&
 
2829
        bltest.options[opt_BufSize].activated) {
 
2830
        fprintf(stderr, "%s: cannot use a nonce as input to decrypt/verify.\n",
 
2831
                         progName);
 
2832
        Usage();
 
2833
    }
 
2834
 
 
2835
    if (bltest.options[opt_Mode].activated) {
 
2836
        cipherInfo.mode = get_mode(bltest.options[opt_Mode].arg);
 
2837
        if (cipherInfo.mode == bltestINVALID) {
 
2838
            fprintf(stderr, "%s: Invalid mode \"%s\"\n", progName,
 
2839
                             bltest.options[opt_Mode].arg);
 
2840
            Usage();
 
2841
        }
 
2842
    } else {
 
2843
        fprintf(stderr, "%s: You must specify a cipher mode with -m.\n",
 
2844
                         progName);
 
2845
        Usage();
 
2846
    }
 
2847
 
 
2848
    if (bltest.options[opt_Repetitions].activated) {
 
2849
        cipherInfo.repetitions = PORT_Atoi(bltest.options[opt_Repetitions].arg);
 
2850
    } else {
 
2851
        cipherInfo.repetitions = 0;
 
2852
    }
 
2853
 
 
2854
 
 
2855
    if (bltest.options[opt_CXReps].activated) {
 
2856
        cipherInfo.cxreps = PORT_Atoi(bltest.options[opt_CXReps].arg);
 
2857
    } else {
 
2858
        cipherInfo.cxreps = 0;
 
2859
    }
 
2860
 
 
2861
    /* Dump a file (rsakey, dsakey, etc.) */
 
2862
    if (bltest.commands[cmd_Dump].activated) {
 
2863
        return dump_file(cipherInfo.mode, bltest.options[opt_Input].arg);
 
2864
    }
 
2865
 
 
2866
    /* default input mode is binary */
 
2867
    ioMode = (bltest.options[opt_B64].activated)     ? bltestBase64Encoded :
 
2868
             (bltest.options[opt_Hex].activated)     ? bltestHexStream :
 
2869
             (bltest.options[opt_HexWSpc].activated) ? bltestHexSpaceDelim :
 
2870
                                                       bltestBinary;
 
2871
 
 
2872
    if (bltest.options[opt_KeySize].activated)
 
2873
        keysize = PORT_Atoi(bltest.options[opt_KeySize].arg);
 
2874
    else
 
2875
        keysize = 0;
 
2876
 
 
2877
    if (bltest.options[opt_Exponent].activated)
 
2878
        exponent = PORT_Atoi(bltest.options[opt_Exponent].arg);
 
2879
    else
 
2880
        exponent = 65537;
 
2881
 
 
2882
#ifdef NSS_ENABLE_ECC
 
2883
    if (bltest.options[opt_CurveName].activated)
 
2884
        curveName = PORT_Strdup(bltest.options[opt_CurveName].arg);
 
2885
    else
 
2886
        curveName = NULL;
 
2887
#endif
 
2888
 
 
2889
    /* Set up an encryption key. */
 
2890
    keysize = 0;
 
2891
    file = NULL;
 
2892
    if (is_symmkeyCipher(cipherInfo.mode)) {
 
2893
        char *keystr = NULL;  /* if key is on command line */
 
2894
        if (bltest.options[opt_Key].activated) {
 
2895
            if (bltest.options[opt_CmdLine].activated) {
 
2896
                keystr = bltest.options[opt_Key].arg;
 
2897
            } else {
 
2898
                file = PR_Open(bltest.options[opt_Key].arg, PR_RDONLY, 00660);
 
2899
            }
 
2900
        } else {
 
2901
            if (bltest.options[opt_KeySize].activated)
 
2902
                keysize = PORT_Atoi(bltest.options[opt_KeySize].arg);
 
2903
            else
 
2904
                keysize = 8; /* use 64-bit default (DES) */
 
2905
            /* save the random key for reference */
 
2906
            file = PR_Open("tmp.key", PR_WRONLY|PR_CREATE_FILE, 00660);
 
2907
        }
 
2908
        params->key.mode = ioMode;
 
2909
        setupIO(cipherInfo.arena, &params->key, file, keystr, keysize);
 
2910
        if (file)
 
2911
            PR_Close(file);
 
2912
    } else if (is_pubkeyCipher(cipherInfo.mode)) {
 
2913
        if (bltest.options[opt_Key].activated) {
 
2914
            file = PR_Open(bltest.options[opt_Key].arg, PR_RDONLY, 00660);
 
2915
        } else {
 
2916
            if (bltest.options[opt_KeySize].activated)
 
2917
                keysize = PORT_Atoi(bltest.options[opt_KeySize].arg);
 
2918
            else
 
2919
                keysize = 64; /* use 512-bit default */
 
2920
            file = PR_Open("tmp.key", PR_WRONLY|PR_CREATE_FILE, 00660);
 
2921
        }
 
2922
        params->key.mode = bltestBase64Encoded;
 
2923
#ifdef NSS_ENABLE_ECC
 
2924
        pubkeyInitKey(&cipherInfo, file, keysize, exponent, curveName);
 
2925
#else
 
2926
        pubkeyInitKey(&cipherInfo, file, keysize, exponent);
 
2927
#endif
 
2928
        PR_Close(file);
 
2929
    }
 
2930
 
 
2931
    /* set up an initialization vector. */
 
2932
    if (cipher_requires_IV(cipherInfo.mode)) {
 
2933
        char *ivstr = NULL;
 
2934
        bltestSymmKeyParams *skp;
 
2935
        file = NULL;
 
2936
        if (cipherInfo.mode == bltestRC5_CBC)
 
2937
            skp = (bltestSymmKeyParams *)&params->rc5;
 
2938
        else
 
2939
            skp = &params->sk;
 
2940
        if (bltest.options[opt_IV].activated) {
 
2941
            if (bltest.options[opt_CmdLine].activated) {
 
2942
                ivstr = bltest.options[opt_IV].arg;
 
2943
            } else {
 
2944
                file = PR_Open(bltest.options[opt_IV].arg, PR_RDONLY, 00660);
 
2945
            }
 
2946
        } else {
 
2947
            /* save the random iv for reference */
 
2948
            file = PR_Open("tmp.iv", PR_WRONLY|PR_CREATE_FILE, 00660);
 
2949
        }
 
2950
        memset(&skp->iv, 0, sizeof skp->iv);
 
2951
        skp->iv.mode = ioMode;
 
2952
        setupIO(cipherInfo.arena, &skp->iv, file, ivstr, keysize);
 
2953
        if (file)
 
2954
            PR_Close(file);
 
2955
    }
 
2956
 
 
2957
    if (bltest.commands[cmd_Verify].activated) {
 
2958
        if (!bltest.options[opt_SigFile].activated) {
 
2959
            fprintf(stderr, "%s: You must specify a signature file with -f.\n",
 
2960
                    progName);
 
2961
            exit(-1);
 
2962
        }
 
2963
        file = PR_Open(bltest.options[opt_SigFile].arg, PR_RDONLY, 00660);
 
2964
        if (cipherInfo.mode == bltestDSA) {
 
2965
            memset(&cipherInfo.params.dsa.sig, 0, sizeof(bltestIO));
 
2966
            cipherInfo.params.dsa.sig.mode = ioMode;
 
2967
            setupIO(cipherInfo.arena, &cipherInfo.params.dsa.sig, file, NULL, 0);
 
2968
#ifdef NSS_ENABLE_ECC
 
2969
        } else if (cipherInfo.mode == bltestECDSA) {
 
2970
            memset(&cipherInfo.params.ecdsa.sig, 0, sizeof(bltestIO));
 
2971
            cipherInfo.params.ecdsa.sig.mode = ioMode;
 
2972
            setupIO(cipherInfo.arena, &cipherInfo.params.ecdsa.sig, file, NULL, 0);
 
2973
#endif
 
2974
        }
 
2975
    }
 
2976
 
 
2977
    if (bltest.options[opt_PQGFile].activated) {
 
2978
        file = PR_Open(bltest.options[opt_PQGFile].arg, PR_RDONLY, 00660);
 
2979
        params->dsa.pqgdata.mode = bltestBase64Encoded;
 
2980
        setupIO(cipherInfo.arena, &params->dsa.pqgdata, file, NULL, 0);
 
2981
    }
 
2982
 
 
2983
    /* Set up the input buffer */
 
2984
    if (bltest.options[opt_Input].activated) {
 
2985
        if (bltest.options[opt_CmdLine].activated) {
 
2986
            instr = bltest.options[opt_Input].arg;
 
2987
            infile = NULL;
 
2988
        } else {
 
2989
            /* form file name from testdir and input arg. */
 
2990
            char * filename = bltest.options[opt_Input].arg;
 
2991
            if (bltest.options[opt_SelfTestDir].activated && 
 
2992
                testdir && filename && filename[0] != '/') 
 
2993
                filename = PR_smprintf("%s/tests/%s/%s", testdir, 
 
2994
                               mode_strings[cipherInfo.mode], filename);
 
2995
            infile = PR_Open(filename, PR_RDONLY, 00660);
 
2996
        }
 
2997
    } else if (bltest.options[opt_BufSize].activated) {
 
2998
        /* save the random plaintext for reference */
 
2999
        infile = PR_Open("tmp.in", PR_WRONLY|PR_CREATE_FILE, 00660);
 
3000
    } else {
 
3001
        infile = PR_STDIN;
 
3002
    }
 
3003
    if (!infile) {
 
3004
        fprintf(stderr, "%s: Failed to open input file.\n", progName);
 
3005
            exit(-1);
 
3006
    }
 
3007
    cipherInfo.input.mode = ioMode;
 
3008
 
 
3009
    /* Set up the output stream */
 
3010
    if (bltest.options[opt_Output].activated) {
 
3011
        /* form file name from testdir and input arg. */
 
3012
        char * filename = bltest.options[opt_Output].arg;
 
3013
        if (bltest.options[opt_SelfTestDir].activated && 
 
3014
            testdir && filename && filename[0] != '/') 
 
3015
            filename = PR_smprintf("%s/tests/%s/%s", testdir, 
 
3016
                       mode_strings[cipherInfo.mode], filename);
 
3017
        outfile = PR_Open(filename, PR_WRONLY|PR_CREATE_FILE, 00660);
 
3018
    } else {
 
3019
        outfile = PR_STDOUT;
 
3020
    }
 
3021
    if (!outfile) {
 
3022
        fprintf(stderr, "%s: Failed to open output file.\n", progName);
 
3023
            exit(-1);
 
3024
    }
 
3025
    cipherInfo.output.mode = ioMode;
 
3026
    if (bltest.options[opt_SelfTestDir].activated && ioMode == bltestBinary)
 
3027
        cipherInfo.output.mode = bltestBase64Encoded;
 
3028
 
 
3029
    if (is_hashCipher(cipherInfo.mode))
 
3030
        cipherInfo.params.hash.restart = bltest.options[opt_Restart].activated;
 
3031
 
 
3032
    bufsize = 0;
 
3033
    if (bltest.options[opt_BufSize].activated)
 
3034
        bufsize = PORT_Atoi(bltest.options[opt_BufSize].arg);
 
3035
 
 
3036
    /*infile = NULL;*/
 
3037
    setupIO(cipherInfo.arena, &cipherInfo.input, infile, instr, bufsize);
 
3038
    misalignBuffer(cipherInfo.arena, &cipherInfo.input, inoff);
 
3039
 
 
3040
    cipherInit(&cipherInfo, bltest.commands[cmd_Encrypt].activated);
 
3041
    misalignBuffer(cipherInfo.arena, &cipherInfo.output, outoff);
 
3042
 
 
3043
    if (!bltest.commands[cmd_Nonce].activated) {
 
3044
        if (bltest.options[opt_MonteCarlo].activated) {
 
3045
            int mciter;
 
3046
            for (mciter=0; mciter<10000; mciter++) {
 
3047
                cipherDoOp(&cipherInfo);
 
3048
                memcpy(cipherInfo.input.buf.data,
 
3049
                       cipherInfo.output.buf.data,
 
3050
                       cipherInfo.input.buf.len);
 
3051
            }
 
3052
        } else {
 
3053
            cipherDoOp(&cipherInfo);
 
3054
        }
 
3055
        cipherFinish(&cipherInfo);
 
3056
        finishIO(&cipherInfo.output, outfile);
 
3057
    }
 
3058
 
 
3059
    if (cipherInfo.repetitions > 0 || cipherInfo.cxreps > 0)
 
3060
        dump_performance_info(&cipherInfo, 
 
3061
                              bltest.commands[cmd_Encrypt].activated,
 
3062
                              (cipherInfo.repetitions == 0));
 
3063
 
 
3064
    if (infile && infile != PR_STDIN)
 
3065
        PR_Close(infile);
 
3066
    if (outfile && outfile != PR_STDOUT)
 
3067
        PR_Close(outfile);
 
3068
    PORT_FreeArena(cipherInfo.arena, PR_TRUE);
 
3069
 
 
3070
    /*NSS_Shutdown();*/
 
3071
 
 
3072
    return SECSuccess;
 
3073
}