summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--security/nss/cmd/rsaperf/Makefile82
-rw-r--r--security/nss/cmd/rsaperf/manifest.mn49
-rw-r--r--security/nss/cmd/rsaperf/rsaperf.c382
3 files changed, 513 insertions, 0 deletions
diff --git a/security/nss/cmd/rsaperf/Makefile b/security/nss/cmd/rsaperf/Makefile
new file mode 100644
index 000000000..cf93911eb
--- /dev/null
+++ b/security/nss/cmd/rsaperf/Makefile
@@ -0,0 +1,82 @@
+#! gmake
+#
+# The contents of this file are subject to the Mozilla Public
+# License Version 1.1 (the "License"); you may not use this file
+# except in compliance with the License. You may obtain a copy of
+# the License at http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS
+# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# rights and limitations under the License.
+#
+# The Original Code is the Netscape security libraries.
+#
+# The Initial Developer of the Original Code is Netscape
+# Communications Corporation. Portions created by Netscape are
+# Copyright (C) 1998-2000 Netscape Communications Corporation. All
+# Rights Reserved.
+#
+# Contributor(s):
+#
+# Alternatively, the contents of this file may be used under the
+# terms of the GNU General Public License Version 2 or later (the
+# "GPL"), in which case the provisions of the GPL are applicable
+# instead of those above. If you wish to allow use of your
+# version of this file only under the terms of the GPL and not to
+# allow others to use your version of this file under the MPL,
+# indicate your decision by deleting the provisions above and
+# replace them with the notice and other provisions required by
+# the GPL. If you do not delete the provisions above, a recipient
+# may use your version of this file under either the MPL or the
+# GPL.
+#
+
+#######################################################################
+# (1) Include initial platform-independent assignments (MANDATORY). #
+#######################################################################
+
+include manifest.mn
+
+#######################################################################
+# (2) Include "global" configuration information. (OPTIONAL) #
+#######################################################################
+
+include $(CORE_DEPTH)/coreconf/config.mk
+
+#######################################################################
+# (3) Include "component" configuration information. (OPTIONAL) #
+#######################################################################
+
+#######################################################################
+# (4) Include "local" platform-dependent assignments (OPTIONAL). #
+#######################################################################
+include ../platlibs.mk
+
+ifeq ($(OS_ARCH), WINNT)
+ifndef BUILD_OPT
+LDFLAGS += /subsystem:console /profile /debug /machine:I386 /incremental:no
+OS_CFLAGS += -D_CONSOLE
+endif
+endif
+
+
+#######################################################################
+# (5) Execute "global" rules. (OPTIONAL) #
+#######################################################################
+
+include $(CORE_DEPTH)/coreconf/rules.mk
+
+#######################################################################
+# (6) Execute "component" rules. (OPTIONAL) #
+#######################################################################
+
+
+
+#######################################################################
+# (7) Execute "local" rules. (OPTIONAL). #
+#######################################################################
+
+
+include ../platrules.mk
+
diff --git a/security/nss/cmd/rsaperf/manifest.mn b/security/nss/cmd/rsaperf/manifest.mn
new file mode 100644
index 000000000..0f044b31f
--- /dev/null
+++ b/security/nss/cmd/rsaperf/manifest.mn
@@ -0,0 +1,49 @@
+#
+# The contents of this file are subject to the Mozilla Public
+# License Version 1.1 (the "License"); you may not use this file
+# except in compliance with the License. You may obtain a copy of
+# the License at http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS
+# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# rights and limitations under the License.
+#
+# The Original Code is the Netscape security libraries.
+#
+# The Initial Developer of the Original Code is Netscape
+# Communications Corporation. Portions created by Netscape are
+# Copyright (C) 1998-2000 Netscape Communications Corporation. All
+# Rights Reserved.
+#
+# Contributor(s):
+#
+# Alternatively, the contents of this file may be used under the
+# terms of the GNU General Public License Version 2 or later (the
+# "GPL"), in which case the provisions of the GPL are applicable
+# instead of those above. If you wish to allow use of your
+# version of this file only under the terms of the GPL and not to
+# allow others to use your version of this file under the MPL,
+# indicate your decision by deleting the provisions above and
+# replace them with the notice and other provisions required by
+# the GPL. If you do not delete the provisions above, a recipient
+# may use your version of this file under either the MPL or the
+# GPL.
+#
+
+DEPTH = ../../..
+CORE_DEPTH = ../../..
+
+# MODULE public and private header directories are implicitly REQUIRED.
+MODULE = security
+
+# This next line is used by .mk files
+# and gets translated into $LINCS in manifest.mnw
+REQUIRES = dbm seccmd
+
+# DIRS =
+
+CSRCS = rsaperf.c defkey.c
+
+PROGRAM = rsaperf
+
diff --git a/security/nss/cmd/rsaperf/rsaperf.c b/security/nss/cmd/rsaperf/rsaperf.c
new file mode 100644
index 000000000..d3587fab1
--- /dev/null
+++ b/security/nss/cmd/rsaperf/rsaperf.c
@@ -0,0 +1,382 @@
+/*
+ * The contents of this file are subject to the Mozilla Public
+ * License Version 1.1 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS
+ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+ * implied. See the License for the specific language governing
+ * rights and limitations under the License.
+ *
+ * The Original Code is the Netscape security libraries.
+ *
+ * The Initial Developer of the Original Code is Netscape
+ * Communications Corporation. Portions created by Netscape are
+ * Copyright (C) 1998-2000 Netscape Communications Corporation. All
+ * Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the
+ * terms of the GNU General Public License Version 2 or later (the
+ * "GPL"), in which case the provisions of the GPL are applicable
+ * instead of those above. If you wish to allow use of your
+ * version of this file only under the terms of the GPL and not to
+ * allow others to use your version of this file under the MPL,
+ * indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by
+ * the GPL. If you do not delete the provisions above, a recipient
+ * may use your version of this file under either the MPL or the
+ * GPL.
+ */
+
+#include "seccomon.h"
+#include "cert.h"
+#include "secutil.h"
+#include "nspr.h"
+#include "nss.h"
+#include "blapi.h"
+#include "plgetopt.h"
+
+
+#define MAX_RSA_MODULUS_BYTES (1024/8)
+#define DEFAULT_ITERS 10
+
+extern SECKEYLowPrivateKey * getDefaultRSAPrivateKey(void);
+extern SECKEYLowPublicKey * getDefaultRSAPublicKey(void);
+
+typedef struct TimingContextStr TimingContext;
+
+struct TimingContextStr {
+ int64 start;
+ int64 end;
+ int64 interval;
+
+ long days;
+ int hours;
+ int minutes;
+ int seconds;
+ int millisecs;
+};
+
+TimingContext *CreateTimingContext(void) {
+ return PR_Malloc(sizeof(TimingContext));
+}
+
+void DestroyTimingContext(TimingContext *ctx) {
+ PR_Free(ctx);
+}
+
+void TimingBegin(TimingContext *ctx) {
+ ctx->start = PR_Now();
+}
+
+static void timingUpdate(TimingContext *ctx) {
+ int64 tmp, remaining;
+ int64 L1000,L60,L24;
+
+ LL_I2L(L1000,1000);
+ LL_I2L(L60,60);
+ LL_I2L(L24,24);
+
+ LL_DIV(remaining, ctx->interval, L1000);
+ LL_MOD(tmp, remaining, L1000);
+ LL_L2I(ctx->millisecs, tmp);
+ LL_DIV(remaining, remaining, L1000);
+ LL_MOD(tmp, remaining, L60);
+ LL_L2I(ctx->seconds, tmp);
+ LL_DIV(remaining, remaining, L60);
+ LL_MOD(tmp, remaining, L60);
+ LL_L2I(ctx->minutes, tmp);
+ LL_DIV(remaining, remaining, L60);
+ LL_MOD(tmp, remaining, L24);
+ LL_L2I(ctx->hours, tmp);
+ LL_DIV(remaining, remaining, L24);
+ LL_L2I(ctx->days, remaining);
+}
+
+void TimingEnd(TimingContext *ctx) {
+ ctx->end = PR_Now();
+ LL_SUB(ctx->interval, ctx->end, ctx->start);
+ PORT_Assert(LL_GE_ZERO(ctx->interval));
+ timingUpdate(ctx);
+}
+
+void TimingDivide(TimingContext *ctx, int divisor) {
+ int64 tmp;
+
+ LL_I2L(tmp, divisor);
+ LL_DIV(ctx->interval, ctx->interval, tmp);
+
+ timingUpdate(ctx);
+}
+
+char *TimingGenerateString(TimingContext *ctx) {
+ char *buf = NULL;
+
+ if (ctx->days != 0) {
+ buf = PR_sprintf_append(buf, "%d days", ctx->days);
+ }
+ if (ctx->hours != 0) {
+ if (buf != NULL) buf = PR_sprintf_append(buf, ", ");
+ buf = PR_sprintf_append(buf, "%d hours", ctx->hours);
+ }
+ if (ctx->minutes != 0) {
+ if (buf != NULL) buf = PR_sprintf_append(buf, ", ");
+ buf = PR_sprintf_append(buf, "%d minutes", ctx->minutes);
+ }
+ if (buf != NULL) buf = PR_sprintf_append(buf, ", and ");
+ if (!buf && ctx->seconds == 0) {
+ int interval;
+ LL_L2I(interval, ctx->interval);
+ if (ctx->millisecs < 100)
+ buf = PR_sprintf_append(buf, "%d microseconds", interval);
+ else
+ buf = PR_sprintf_append(buf, "%d milliseconds", ctx->millisecs);
+ } else if (ctx->millisecs == 0) {
+ buf = PR_sprintf_append(buf, "%d seconds", ctx->seconds);
+ } else {
+ buf = PR_sprintf_append(buf, "%d.%03d seconds",
+ ctx->seconds, ctx->millisecs);
+ }
+ return buf;
+}
+
+void
+Usage(char *progName)
+{
+ fprintf(stderr, "Usage: %s [-d certdir] [-i iterations] [-s | -e]"
+ " -n nickname\n",
+ progName);
+ fprintf(stderr, "%-20s Cert database directory (default is ~/.netscape)\n",
+ "-d certdir");
+ fprintf(stderr, "%-20s How many operations to perform\n", "-i iterations");
+ fprintf(stderr, "%-20s Perform signing (private key) operations\n", "-s");
+ fprintf(stderr, "%-20s Perform encryption (public key) operations\n", "-e");
+ fprintf(stderr, "%-20s Nickname of certificate or key\n", "-n nickname");
+ exit(-1);
+}
+
+void
+printCount(int iterations)
+{
+
+}
+
+
+static void
+dumpBytes( unsigned char * b, int l)
+{
+ int i;
+ if (l <= 0)
+ return;
+ for (i = 0; i < l; ++i) {
+ if (i % 16 == 0)
+ printf("\t");
+ printf(" %02x", b[i]);
+ if (i % 16 == 15)
+ printf("\n");
+ }
+ if ((i % 16) != 0)
+ printf("\n");
+}
+
+static void
+dumpItem( SECItem * item, const char * description)
+{
+ if (item->len & 1 && item->data[0] == 0) {
+ printf("%s: (%d bytes)\n", description, item->len - 1);
+ dumpBytes(item->data + 1, item->len - 1);
+ } else {
+ printf("%s: (%d bytes)\n", description, item->len);
+ dumpBytes(item->data, item->len);
+ }
+}
+
+void
+printPrivKey(SECKEYLowPrivateKey * privKey)
+{
+ RSAPrivateKey *rsa = &privKey->u.rsa;
+
+ dumpItem( &rsa->modulus, "n");
+ dumpItem( &rsa->publicExponent, "e");
+ dumpItem( &rsa->privateExponent, "d");
+ dumpItem( &rsa->prime1, "P");
+ dumpItem( &rsa->prime2, "Q");
+ dumpItem( &rsa->exponent1, "d % (P-1)");
+ dumpItem( &rsa->exponent2, "d % (Q-1)");
+ dumpItem( &rsa->coefficient, "(Q ** -1) % P");
+ puts("");
+}
+
+void
+printFnCounts(long doPrint)
+{
+
+}
+
+typedef SECStatus (* RSAOp)(void * key,
+ unsigned char * output,
+ unsigned char * input);
+
+
+int
+main(int argc, char **argv)
+{
+ TimingContext * timeCtx;
+ SECKEYKeyDBHandle * keydb;
+ SECKEYPublicKey * pubHighKey;
+ SECKEYLowPrivateKey * privKey;
+ SECKEYLowPublicKey * pubKey;
+ CERTCertificate * cert;
+ char * progName;
+ char * secDir = NULL;
+ char * nickname = NULL;
+ RSAOp fn;
+ void * rsaKey;
+ PLOptState * optstate;
+ PLOptStatus optstatus;
+ long iters = DEFAULT_ITERS;
+ int i;
+ PRBool doPriv = PR_FALSE;
+ PRBool doPub = PR_FALSE;
+ int rv;
+ CERTCertDBHandle * certdb;
+ unsigned char buf[1024];
+ unsigned char buf2[1024];
+
+ progName = strrchr(argv[0], '/');
+ if (!progName)
+ progName = strrchr(argv[0], '\\');
+ progName = progName ? progName+1 : argv[0];
+
+ optstate = PL_CreateOptState(argc, argv, "d:i:sen:");
+ while ((optstatus = PL_GetNextOpt(optstate)) == PL_OPT_OK) {
+ switch (optstate->option) {
+ case '?':
+ Usage(progName);
+ break;
+ case 'd':
+ secDir = PORT_Strdup(optstate->value);
+ break;
+ case 'i':
+ iters = atol(optstate->value);
+ break;
+ case 's':
+ doPriv = PR_TRUE;
+ break;
+ case 'e':
+ doPub = PR_TRUE;
+ break;
+ case 'n':
+ nickname = PORT_Strdup(optstate->value);
+ break;
+ }
+ }
+ if (optstatus == PL_OPT_BAD)
+ Usage(progName);
+
+ if ((doPriv && doPub) || (nickname == NULL)) Usage(progName);
+
+ if (!doPriv && !doPub) doPriv = PR_TRUE;
+
+ PR_Init( PR_SYSTEM_THREAD, PR_PRIORITY_NORMAL, 1);
+
+ secDir = SECU_ConfigDirectory(secDir);
+ rv = NSS_Init(secDir);
+ if (rv != SECSuccess) {
+ fprintf(stderr, "NSS_Init failed.\n");
+ exit(1);
+ }
+ certdb = CERT_GetDefaultCertDB();
+ keydb = SECKEY_GetDefaultKeyDB();
+
+ if (doPub) {
+ if (!strcmp(nickname, "none")) {
+ pubKey = getDefaultRSAPublicKey();
+ } else {
+ cert = CERT_FindCertByNickname(certdb, nickname);
+ if (cert == NULL) {
+ fprintf(stderr,
+ "Can't find certificate by name \"%s\"\n", nickname);
+ exit(1);
+ }
+ pubHighKey = CERT_ExtractPublicKey(cert);
+ pubKey = SECU_ConvHighToLow(pubHighKey);
+ }
+ if (pubKey == NULL) {
+ fprintf(stderr, "Can't extract public key from certificate");
+ exit(1);
+ }
+ fn = (RSAOp)RSA_PublicKeyOp;
+ rsaKey = (void *)(&pubKey->u.rsa);
+ }
+
+ if (doPriv) {
+
+ if (!strcmp(nickname, "none")) {
+ privKey = getDefaultRSAPrivateKey();
+ } else {
+ cert = CERT_FindCertByNickname(certdb, nickname);
+ if (cert == NULL) {
+ fprintf(stderr,
+ "Can't find certificate by name \"%s\"\n", nickname);
+ exit(1);
+ }
+
+ privKey = SECKEY_FindKeyByCert(keydb, cert, SECU_GetPassword, NULL);
+ }
+ if (privKey == NULL) {
+ fprintf(stderr,
+ "Can't find private key by name \"%s\"\n", nickname);
+ exit(1);
+ }
+
+#if 0
+ printPrivKey(privKey);
+#endif
+ fn = (RSAOp)RSA_PrivateKeyOp;
+ rsaKey = (void *)(&privKey->u.rsa);
+ }
+
+ memset(buf, 1, sizeof buf);
+ rv = fn(rsaKey, buf2, buf);
+ if (rv != SECSuccess) {
+ PRErrorCode errNum;
+ const char * errStr = NULL;
+
+ errNum = PR_GetError();
+ if (errNum)
+ errStr = SECU_Strerror(errNum);
+ else
+ errNum = rv;
+ if (!errStr)
+ errStr = "(null)";
+ fprintf(stderr, "Error in RSA operation: %d : %s\n", errNum, errStr);
+ exit(1);
+ }
+
+/* printf("START\n"); */
+
+ timeCtx = CreateTimingContext();
+ TimingBegin(timeCtx);
+ i = iters;
+ while (i--) {
+ rv = fn(rsaKey, buf2, buf);
+ if (rv != SECSuccess) {
+ PRErrorCode errNum = PR_GetError();
+ const char * errStr = SECU_Strerror(errNum);
+ fprintf(stderr, "Error in RSA operation: %d : %s\n",
+ errNum, errStr);
+ exit(1);
+ }
+ }
+ TimingEnd(timeCtx);
+ printf("%ld iterations in %s\n",
+ iters, TimingGenerateString(timeCtx));
+ TimingDivide(timeCtx, iters);
+ printf("one operation every %s\n", TimingGenerateString(timeCtx));
+
+ return 0;
+}