Bug Summary

File:s/cmd/ecperf/ecperf.c
Warning:line 144, column 14
Function taking 4 arguments is called with fewer (3)

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name ecperf.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -analyzer-config-compatibility-mode=true -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -mframe-pointer=all -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fdebug-compilation-dir=/var/lib/jenkins/workspace/nss-scan-build/nss/cmd/ecperf -ffunction-sections -fdata-sections -fcoverage-compilation-dir=/var/lib/jenkins/workspace/nss-scan-build/nss/cmd/ecperf -resource-dir /usr/lib/llvm-18/lib/clang/18 -D HAVE_STRERROR -D LINUX -D linux -D XP_UNIX -D XP_UNIX -D DEBUG -U NDEBUG -D _DEFAULT_SOURCE -D _BSD_SOURCE -D _POSIX_SOURCE -D SDB_MEASURE_USE_TEMP_DIR -D _REENTRANT -D DEBUG -U NDEBUG -D _DEFAULT_SOURCE -D _BSD_SOURCE -D _POSIX_SOURCE -D SDB_MEASURE_USE_TEMP_DIR -D _REENTRANT -D NSS_DISABLE_SSE3 -D NSS_NO_INIT_SUPPORT -D USE_UTIL_DIRECTLY -D NO_NSPR_10_SUPPORT -D SSL_DISABLE_DEPRECATED_CIPHER_SUITE_NAMES -D NSS_USE_STATIC_LIBS -I ../../nss/lib/softoken -I ../../../dist/Linux4.19_x86_64_gcc_glibc_PTH_64_DBG.OBJ/include -I ../../../dist/public/nss -I ../../../dist/private/nss -internal-isystem /usr/lib/llvm-18/lib/clang/18/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -std=c99 -ferror-limit 19 -fgnuc-version=4.2.1 -analyzer-output=html -analyzer-config stable-report-filename=true -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /tmp/scan-build-2024-05-18-082241-28900-1 -x c ecperf.c
1/* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4
5#include "blapi.h"
6#include "ec.h"
7#include "ecl-curve.h"
8#include "prprf.h"
9#include "basicutil.h"
10#include "pkcs11.h"
11#include "nspr.h"
12#include <stdio.h>
13
14#define __PASTE(x, y)xy x##y
15
16/*
17 * Get the NSS specific PKCS #11 function names.
18 */
19#undef CK_PKCS11_FUNCTION_INFO
20#undef CK_NEED_ARG_LIST1
21
22#define CK_EXTERNextern extern
23#define CK_PKCS11_FUNCTION_INFO(func)CK_RV NSfunc \
24 CK_RV __PASTE(NS, func)NSfunc
25#define CK_NEED_ARG_LIST1 1
26
27#include "pkcs11f.h"
28
29typedef SECStatus (*op_func)(void *, void *, void *);
30typedef SECStatus (*pk11_op_func)(CK_SESSION_HANDLE, void *, void *, void *);
31
32typedef struct ThreadDataStr {
33 op_func op;
34 void *p1;
35 void *p2;
36 void *p3;
37 int iters;
38 PRLock *lock;
39 int count;
40 SECStatus status;
41 int isSign;
42} ThreadData;
43
44typedef SECItem SECKEYECParams;
45
46void
47PKCS11Thread(void *data)
48{
49 ThreadData *threadData = (ThreadData *)data;
50 pk11_op_func op = (pk11_op_func)threadData->op;
51 int iters = threadData->iters;
52 unsigned char sigData[256];
53 SECItem sig;
54 CK_SESSION_HANDLE session;
55 CK_RV crv;
56 void *tmp = NULL((void*)0);
57
58 threadData->status = SECSuccess;
59 threadData->count = 0;
60
61 /* get our thread's session */
62 PR_Lock(threadData->lock);
63 crv = NSC_OpenSession(1, CKF_SERIAL_SESSION0x00000004UL, NULL((void*)0), 0, &session);
64 PR_Unlock(threadData->lock);
65 if (crv != CKR_OK0x00000000UL) {
66 return;
67 }
68
69 if (threadData->isSign) {
70 sig.data = sigData;
71 sig.len = sizeof(sigData);
72 tmp = threadData->p2;
73 threadData->p2 = (void *)&sig;
74 }
75
76 while (iters--) {
77 threadData->status = (*op)(session, threadData->p1,
78 threadData->p2, threadData->p3);
79 if (threadData->status != SECSuccess) {
80 break;
81 }
82 threadData->count++;
83 }
84
85 if (threadData->isSign) {
86 threadData->p2 = tmp;
87 }
88 return;
89}
90
91void
92genericThread(void *data)
93{
94 ThreadData *threadData = (ThreadData *)data;
95 int iters = threadData->iters;
96 unsigned char sigData[256];
97 SECItem sig;
98 void *tmp = NULL((void*)0);
99
100 threadData->status = SECSuccess;
101 threadData->count = 0;
102
103 if (threadData->isSign) {
104 sig.data = sigData;
105 sig.len = sizeof(sigData);
106 tmp = threadData->p2;
107 threadData->p2 = (void *)&sig;
108 }
109
110 while (iters--) {
111 threadData->status = (*threadData->op)(threadData->p1,
112 threadData->p2, threadData->p3);
113 if (threadData->status != SECSuccess) {
114 break;
115 }
116 threadData->count++;
117 }
118
119 if (threadData->isSign) {
120 threadData->p2 = tmp;
121 }
122 return;
123}
124
125/* Time iter repetitions of operation op. */
126SECStatus
127M_TimeOperation(void (*threadFunc)(void *),
128 op_func opfunc, char *op, void *param1, void *param2,
129 void *param3, int iters, int numThreads, PRLock *lock,
130 CK_SESSION_HANDLE session, int isSign, double *rate)
131{
132 double dUserTime;
133 int i, total;
134 PRIntervalTime startTime, totalTime;
135 PRThread **threadIDs;
136 ThreadData *threadData;
137 pk11_op_func pk11_op = (pk11_op_func)opfunc;
138 SECStatus rv;
139
140 /* verify operation works before testing performance */
141 if (session) {
43
Assuming 'session' is 0
44
Taking false branch
142 rv = (*pk11_op)(session, param1, param2, param3);
143 } else {
144 rv = (*opfunc)(param1, param2, param3);
45
Function taking 4 arguments is called with fewer (3)
145 }
146 if (rv != SECSuccess) {
147 SECU_PrintError("Error:", op);
148 return rv;
149 }
150
151 /* get Data structures */
152 threadIDs = (PRThread **)PORT_AllocPORT_Alloc_Util(numThreads * sizeof(PRThread *));
153 threadData = (ThreadData *)PORT_AllocPORT_Alloc_Util(numThreads * sizeof(ThreadData));
154
155 startTime = PR_Now();
156 if (numThreads == 1) {
157 for (i = 0; i < iters; i++) {
158 if (session) {
159 rv = (*pk11_op)(session, param1, param2, param3);
160 } else {
161 rv = (*opfunc)(param1, param2, param3);
162 }
163 if (rv != SECSuccess) {
164 PORT_FreePORT_Free_Util(threadIDs);
165 PORT_FreePORT_Free_Util(threadData);
166 SECU_PrintError("Error:", op);
167 return rv;
168 }
169 }
170 total = iters;
171 } else {
172 for (i = 0; i < numThreads; i++) {
173 threadData[i].op = opfunc;
174 threadData[i].p1 = (void *)param1;
175 threadData[i].p2 = (void *)param2;
176 threadData[i].p3 = (void *)param3;
177 threadData[i].iters = iters;
178 threadData[i].lock = lock;
179 threadData[i].isSign = isSign;
180 threadIDs[i] = PR_CreateThread(PR_USER_THREAD, threadFunc,
181 (void *)&threadData[i], PR_PRIORITY_NORMAL,
182 PR_GLOBAL_THREAD, PR_JOINABLE_THREAD, 0);
183 }
184
185 total = 0;
186 for (i = 0; i < numThreads; i++) {
187 PR_JoinThread(threadIDs[i]);
188 /* check the status */
189 total += threadData[i].count;
190 }
191 }
192
193 totalTime = PR_Now() - startTime;
194 /* SecondsToInterval seems to be broken here ... */
195 dUserTime = (double)totalTime / (double)1000000;
196 if (dUserTime) {
197 printf(" %-15s count:%4d sec: %3.2f op/sec: %6.2f\n",
198 op, total, dUserTime, (double)total / dUserTime);
199 if (rate) {
200 *rate = ((double)total) / dUserTime;
201 }
202 }
203 PORT_FreePORT_Free_Util(threadIDs);
204 PORT_FreePORT_Free_Util(threadData);
205
206 return SECSuccess;
207}
208
209/* Test curve using specific field arithmetic. */
210#define ECTEST_NAMED_GFP(name_c, name_v)if (usefreebl) { printf("Testing %s using freebl implementation...\n"
, name_c); rv = ectest_curve_freebl(name_v, iterations, numThreads
, ec_field_GFp); if (rv != SECSuccess) goto cleanup; printf("... okay.\n"
); } if (usepkcs11) { printf("Testing %s using pkcs11 implementation...\n"
, name_c); rv = ectest_curve_pkcs11(name_v, iterations, numThreads
); if (rv != SECSuccess) goto cleanup; printf("... okay.\n");
}
\
211 if (usefreebl) { \
212 printf("Testing %s using freebl implementation...\n", name_c); \
213 rv = ectest_curve_freebl(name_v, iterations, numThreads, ec_field_GFp); \
214 if (rv != SECSuccess) \
215 goto cleanup; \
216 printf("... okay.\n"); \
217 } \
218 if (usepkcs11) { \
219 printf("Testing %s using pkcs11 implementation...\n", name_c); \
220 rv = ectest_curve_pkcs11(name_v, iterations, numThreads); \
221 if (rv != SECSuccess) \
222 goto cleanup; \
223 printf("... okay.\n"); \
224 }
225
226/* Test curve using specific field arithmetic. */
227#define ECTEST_NAMED_CUSTOM(name_c, name_v)if (usefreebl) { printf("Testing %s using freebl implementation...\n"
, name_c); rv = ectest_curve_freebl(name_v, iterations, numThreads
, ec_field_plain); if (rv != SECSuccess) goto cleanup; printf
("... okay.\n"); } if (usepkcs11) { printf("Testing %s using pkcs11 implementation...\n"
, name_c); rv = ectest_curve_pkcs11(name_v, iterations, numThreads
); if (rv != SECSuccess) goto cleanup; printf("... okay.\n");
}
\
228 if (usefreebl) { \
229 printf("Testing %s using freebl implementation...\n", name_c); \
230 rv = ectest_curve_freebl(name_v, iterations, numThreads, ec_field_plain); \
231 if (rv != SECSuccess) \
232 goto cleanup; \
233 printf("... okay.\n"); \
234 } \
235 if (usepkcs11) { \
236 printf("Testing %s using pkcs11 implementation...\n", name_c); \
237 rv = ectest_curve_pkcs11(name_v, iterations, numThreads); \
238 if (rv != SECSuccess) \
239 goto cleanup; \
240 printf("... okay.\n"); \
241 }
242
243#define PK11_SETATTRS(x, id, v, l)(x)->type = (id); (x)->pValue = (v); (x)->ulValueLen
= (l);
\
244 (x)->type = (id); \
245 (x)->pValue = (v); \
246 (x)->ulValueLen = (l);
247
248SECStatus
249PKCS11_Derive(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE *hKey,
250 CK_MECHANISM *pMech, int *dummy)
251{
252 CK_RV crv;
253 CK_OBJECT_HANDLE newKey;
254 CK_BBOOL cktrue = CK_TRUE1;
255 CK_OBJECT_CLASS keyClass = CKO_SECRET_KEY0x00000004UL;
256 CK_KEY_TYPE keyType = CKK_GENERIC_SECRET0x00000010UL;
257 CK_ATTRIBUTE keyTemplate[3];
258 CK_ATTRIBUTE *attrs = keyTemplate;
259
260 PK11_SETATTRS(attrs, CKA_CLASS, &keyClass, sizeof(keyClass))(attrs)->type = (0x00000000UL); (attrs)->pValue = (&
keyClass); (attrs)->ulValueLen = (sizeof(keyClass));
;
261 attrs++;
262 PK11_SETATTRS(attrs, CKA_KEY_TYPE, &keyType, sizeof(keyType))(attrs)->type = (0x00000100UL); (attrs)->pValue = (&
keyType); (attrs)->ulValueLen = (sizeof(keyType));
;
263 attrs++;
264 PK11_SETATTRS(attrs, CKA_DERIVE, &cktrue, 1)(attrs)->type = (0x0000010CUL); (attrs)->pValue = (&
cktrue); (attrs)->ulValueLen = (1);
;
265 attrs++;
266
267 crv = NSC_DeriveKey(session, pMech, *hKey, keyTemplate, 3, &newKey);
268 if (crv != CKR_OK0x00000000UL) {
269 printf("Derive Failed CK_RV=0x%x\n", (int)crv);
270 return SECFailure;
271 }
272 return SECSuccess;
273}
274
275SECStatus
276PKCS11_Sign(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE *hKey,
277 SECItem *sig, SECItem *digest)
278{
279 CK_RV crv;
280 CK_MECHANISM mech;
281 CK_ULONG sigLen = sig->len;
282
283 mech.mechanism = CKM_ECDSA0x00001041UL;
284 mech.pParameter = NULL((void*)0);
285 mech.ulParameterLen = 0;
286
287 crv = NSC_SignInit(session, &mech, *hKey);
288 if (crv != CKR_OK0x00000000UL) {
289 printf("Sign Failed CK_RV=0x%x\n", (int)crv);
290 return SECFailure;
291 }
292 crv = NSC_Sign(session, digest->data, digest->len, sig->data, &sigLen);
293 if (crv != CKR_OK0x00000000UL) {
294 printf("Sign Failed CK_RV=0x%x\n", (int)crv);
295 return SECFailure;
296 }
297 sig->len = (unsigned int)sigLen;
298 return SECSuccess;
299}
300
301SECStatus
302PKCS11_Verify(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE *hKey,
303 SECItem *sig, SECItem *digest)
304{
305 CK_RV crv;
306 CK_MECHANISM mech;
307
308 mech.mechanism = CKM_ECDSA0x00001041UL;
309 mech.pParameter = NULL((void*)0);
310 mech.ulParameterLen = 0;
311
312 crv = NSC_VerifyInit(session, &mech, *hKey);
313 if (crv != CKR_OK0x00000000UL) {
314 printf("Verify Failed CK_RV=0x%x\n", (int)crv);
315 return SECFailure;
316 }
317 crv = NSC_Verify(session, digest->data, digest->len, sig->data, sig->len);
318 if (crv != CKR_OK0x00000000UL) {
319 printf("Verify Failed CK_RV=0x%x\n", (int)crv);
320 return SECFailure;
321 }
322 return SECSuccess;
323}
324
325/* Performs basic tests of elliptic curve cryptography over prime fields.
326 * If tests fail, then it prints an error message, aborts, and returns an
327 * error code. Otherwise, returns 0. */
328SECStatus
329ectest_curve_pkcs11(ECCurveName curve, int iterations, int numThreads)
330{
331 CK_OBJECT_HANDLE ecPriv;
332 CK_OBJECT_HANDLE ecPub;
333 CK_SESSION_HANDLE session;
334 SECItem sig;
335 SECItem digest;
336 SECKEYECParams ecParams;
337 CK_MECHANISM mech;
338 CK_ECDH1_DERIVE_PARAMS ecdh_params;
339 unsigned char sigData[256];
340 unsigned char digestData[20];
341 unsigned char pubKeyData[256];
342 PRLock *lock = NULL((void*)0);
343 double signRate, deriveRate = 0;
344 CK_ATTRIBUTE template;
345 SECStatus rv;
346 CK_RV crv;
347
348 ecParams.data = NULL((void*)0);
349 ecParams.len = 0;
350 rv = SECU_ecName2params(curve, &ecParams);
351 if (rv != SECSuccess) {
32
Assuming 'rv' is equal to SECSuccess
33
Taking false branch
352 goto cleanup;
353 }
354
355 crv = NSC_OpenSession(1, CKF_SERIAL_SESSION0x00000004UL, NULL((void*)0), 0, &session);
356 if (crv != CKR_OK0x00000000UL) {
34
Assuming 'crv' is equal to CKR_OK
35
Taking false branch
357 printf("OpenSession Failed CK_RV=0x%x\n", (int)crv);
358 return SECFailure;
359 }
360
361 PORT_Memsetmemset(digestData, 0xa5, sizeof(digestData));
362 digest.data = digestData;
363 digest.len = sizeof(digestData);
364 sig.data = sigData;
365 sig.len = sizeof(sigData);
366
367 template.type = CKA_EC_PARAMS0x00000180UL;
368 template.pValue = ecParams.data;
369 template.ulValueLen = ecParams.len;
370 mech.mechanism = CKM_EC_KEY_PAIR_GEN0x00001040UL;
371 mech.pParameter = NULL((void*)0);
372 mech.ulParameterLen = 0;
373 crv = NSC_GenerateKeyPair(session, &mech,
374 &template, 1, NULL((void*)0), 0, &ecPub, &ecPriv);
375 if (crv != CKR_OK0x00000000UL) {
36
Assuming 'crv' is equal to CKR_OK
37
Taking false branch
376 printf("GenerateKeyPair Failed CK_RV=0x%x\n", (int)crv);
377 return SECFailure;
378 }
379
380 template.type = CKA_EC_POINT0x00000181UL;
381 template.pValue = pubKeyData;
382 template.ulValueLen = sizeof(pubKeyData);
383 crv = NSC_GetAttributeValue(session, ecPub, &template, 1);
384 if (crv != CKR_OK0x00000000UL) {
38
Assuming 'crv' is equal to CKR_OK
39
Taking false branch
385 printf("GenerateKeyPair Failed CK_RV=0x%x\n", (int)crv);
386 return SECFailure;
387 }
388
389 ecdh_params.kdf = CKD_NULL0x00000001UL;
390 ecdh_params.ulSharedDataLen = 0;
391 ecdh_params.pSharedData = NULL((void*)0);
392 ecdh_params.ulPublicDataLen = template.ulValueLen;
393 ecdh_params.pPublicData = template.pValue;
394
395 mech.mechanism = CKM_ECDH1_DERIVE0x00001050UL;
396 mech.pParameter = (void *)&ecdh_params;
397 mech.ulParameterLen = sizeof(ecdh_params);
398
399 lock = PR_NewLock();
400
401 if (ecCurve_map[curve]->usage & KU_KEY_AGREEMENT(0x08)) {
40
Assuming the condition is true
41
Taking true branch
402 rv = M_TimeOperation(PKCS11Thread, (op_func)PKCS11_Derive, "ECDH_Derive",
42
Calling 'M_TimeOperation'
403 &ecPriv, &mech, NULL((void*)0), iterations, numThreads,
404 lock, session, 0, &deriveRate);
405 if (rv != SECSuccess) {
406 goto cleanup;
407 }
408 }
409
410 if (ecCurve_map[curve]->usage & KU_DIGITAL_SIGNATURE(0x80)) {
411 rv = M_TimeOperation(PKCS11Thread, (op_func)PKCS11_Sign, "ECDSA_Sign",
412 (void *)&ecPriv, &sig, &digest, iterations, numThreads,
413 lock, session, 1, &signRate);
414 if (rv != SECSuccess) {
415 goto cleanup;
416 }
417 printf(" ECDHE max rate = %.2f\n", (deriveRate + signRate) / 4.0);
418 /* get a signature */
419 rv = PKCS11_Sign(session, &ecPriv, &sig, &digest);
420 if (rv != SECSuccess) {
421 goto cleanup;
422 }
423 rv = M_TimeOperation(PKCS11Thread, (op_func)PKCS11_Verify, "ECDSA_Verify",
424 (void *)&ecPub, &sig, &digest, iterations, numThreads,
425 lock, session, 0, NULL((void*)0));
426 if (rv != SECSuccess) {
427 goto cleanup;
428 }
429 }
430
431cleanup:
432 if (lock) {
433 PR_DestroyLock(lock);
434 }
435 return rv;
436}
437
438SECStatus
439ECDH_DeriveWrap(ECPrivateKey *priv, ECPublicKey *pub, int *dummy)
440{
441 SECItem secret;
442 unsigned char secretData[256];
443 SECStatus rv;
444
445 secret.data = secretData;
446 secret.len = sizeof(secretData);
447
448 rv = ECDH_Derive(&pub->publicValue, &pub->ecParams,
449 &priv->privateValue, 0, &secret);
450 SECITEM_FreeItemSECITEM_FreeItem_Util(&secret, PR_FALSE0);
451 return rv;
452}
453
454/* Performs basic tests of elliptic curve cryptography over prime fields.
455 * If tests fail, then it prints an error message, aborts, and returns an
456 * error code. Otherwise, returns 0. */
457SECStatus
458ectest_curve_freebl(ECCurveName curve, int iterations, int numThreads,
459 ECFieldType fieldType)
460{
461 ECParams ecParams = { 0 };
462 ECPrivateKey *ecPriv = NULL((void*)0);
463 ECPublicKey ecPub;
464 SECItem sig;
465 SECItem digest;
466 unsigned char sigData[256];
467 unsigned char digestData[20];
468 double signRate, deriveRate = 0;
469 SECStatus rv = SECFailure;
470 PLArenaPool *arena;
471 SECItem ecEncodedParams = { siBuffer, NULL((void*)0), 0 };
472
473 arena = PORT_NewArenaPORT_NewArena_Util(DER_DEFAULT_CHUNKSIZE(2048));
474 if (!arena) {
475 return SECFailure;
476 }
477
478 if ((curve < ECCurve_noName) || (curve > ECCurve_pastLastCurve)) {
479 PORT_FreeArenaPORT_FreeArena_Util(arena, PR_FALSE0);
480 return SECFailure;
481 }
482
483 rv = SECU_ecName2params(curve, &ecEncodedParams);
484 if (rv != SECSuccess) {
485 goto cleanup;
486 }
487 EC_FillParams(arena, &ecEncodedParams, &ecParams);
488
489 PORT_Memsetmemset(digestData, 0xa5, sizeof(digestData));
490 digest.data = digestData;
491 digest.len = sizeof(digestData);
492 sig.data = sigData;
493 sig.len = sizeof(sigData);
494
495 rv = EC_NewKey(&ecParams, &ecPriv);
496 if (rv != SECSuccess) {
497 goto cleanup;
498 }
499 ecPub.ecParams = ecParams;
500 ecPub.publicValue = ecPriv->publicValue;
501
502 if (ecCurve_map[curve]->usage & KU_KEY_AGREEMENT(0x08)) {
503 rv = M_TimeOperation(genericThread, (op_func)ECDH_DeriveWrap, "ECDH_Derive",
504 ecPriv, &ecPub, NULL((void*)0), iterations, numThreads, 0, 0, 0, &deriveRate);
505 if (rv != SECSuccess) {
506 goto cleanup;
507 }
508 }
509
510 if (ecCurve_map[curve]->usage & KU_DIGITAL_SIGNATURE(0x80)) {
511 rv = M_TimeOperation(genericThread, (op_func)ECDSA_SignDigest, "ECDSA_Sign",
512 ecPriv, &sig, &digest, iterations, numThreads, 0, 0, 1, &signRate);
513 if (rv != SECSuccess)
514 goto cleanup;
515 printf(" ECDHE max rate = %.2f\n", (deriveRate + signRate) / 4.0);
516 rv = ECDSA_SignDigest(ecPriv, &sig, &digest);
517 if (rv != SECSuccess) {
518 goto cleanup;
519 }
520 rv = M_TimeOperation(genericThread, (op_func)ECDSA_VerifyDigest, "ECDSA_Verify",
521 &ecPub, &sig, &digest, iterations, numThreads, 0, 0, 0, NULL((void*)0));
522 if (rv != SECSuccess) {
523 goto cleanup;
524 }
525 }
526
527cleanup:
528 SECITEM_FreeItemSECITEM_FreeItem_Util(&ecEncodedParams, PR_FALSE0);
529 PORT_FreeArenaPORT_FreeArena_Util(arena, PR_FALSE0);
530 if (ecPriv) {
531 PORT_FreeArenaPORT_FreeArena_Util(ecPriv->ecParams.arena, PR_FALSE0);
532 }
533 return rv;
534}
535
536/* Prints help information. */
537void
538printUsage(char *prog)
539{
540 printf("Usage: %s [-i iterations] [-t threads ] [-ans] [-fp] [-Al]\n"
541 "-a: ansi\n-n: nist\n-s: secp\n-f: usefreebl\n-p: usepkcs11\n-A: all\n",
542 prog);
543}
544
545/* Performs tests of elliptic curve cryptography over prime fields If
546 * tests fail, then it prints an error message, aborts, and returns an
547 * error code. Otherwise, returns 0. */
548int
549main(int argv, char **argc)
550{
551 int ansi = 0;
552 int nist = 0;
553 int secp = 0;
554 int usefreebl = 0;
555 int usepkcs11 = 0;
556 int i;
557 SECStatus rv = SECSuccess;
558 int iterations = 100;
559 int numThreads = 1;
560
561 const CK_C_INITIALIZE_ARGS pk11args = {
562 NULL((void*)0), NULL((void*)0), NULL((void*)0), NULL((void*)0), CKF_LIBRARY_CANT_CREATE_OS_THREADS0x00000001UL,
563 (void *)"flags=readOnly,noCertDB,noModDB", NULL((void*)0)
564 };
565
566 /* read command-line arguments */
567 for (i = 1; i < argv; i++) {
1
Assuming 'i' is < 'argv'
2
Loop condition is true. Entering loop body
17
Assuming 'i' is >= 'argv'
18
Loop condition is false. Execution continues on line 593
568 if (PL_strcasecmp(argc[i], "-i") == 0) {
3
Assuming the condition is false
4
Taking false branch
569 i++;
570 iterations = atoi(argc[i]);
571 } else if (PL_strcasecmp(argc[i], "-t") == 0) {
5
Assuming the condition is false
6
Taking false branch
572 i++;
573 numThreads = atoi(argc[i]);
574 } else if (PL_strcasecmp(argc[i], "-A") == 0) {
7
Assuming the condition is false
8
Taking false branch
575 ansi = nist = secp = 1;
576 usepkcs11 = usefreebl = 1;
577 } else if (PL_strcasecmp(argc[i], "-a") == 0) {
9
Assuming the condition is false
10
Taking false branch
578 ansi = 1;
579 } else if (PL_strcasecmp(argc[i], "-n") == 0) {
11
Assuming the condition is false
12
Taking false branch
580 nist = 1;
581 } else if (PL_strcasecmp(argc[i], "-s") == 0) {
13
Assuming the condition is false
14
Taking false branch
582 secp = 1;
583 } else if (PL_strcasecmp(argc[i], "-p") == 0) {
15
Assuming the condition is true
16
Taking true branch
584 usepkcs11 = 1;
585 } else if (PL_strcasecmp(argc[i], "-f") == 0) {
586 usefreebl = 1;
587 } else {
588 printUsage(argc[0]);
589 return 0;
590 }
591 }
592
593 if ((ansi | nist | secp) == 0) {
19
Taking true branch
594 nist = 1;
595 }
596 if ((usepkcs11 | usefreebl) == 0) {
20
Taking false branch
597 usefreebl = 1;
598 }
599
600 rv = RNG_RNGInit();
601 if (rv != SECSuccess) {
21
Assuming 'rv' is equal to SECSuccess
22
Taking false branch
602 SECU_PrintError("Error:", "RNG_RNGInit");
603 return -1;
604 }
605 RNG_SystemInfoForRNG();
606
607 rv = SECOID_Init();
608 if (rv != SECSuccess) {
23
Assuming 'rv' is equal to SECSuccess
24
Taking false branch
609 SECU_PrintError("Error:", "SECOID_Init");
610 goto cleanup;
611 }
612
613 if (usepkcs11
24.1
'usepkcs11' is 1
) {
25
Taking true branch
614 CK_RV crv = NSC_Initialize((CK_VOID_PTR)&pk11args);
615 if (crv != CKR_OK0x00000000UL) {
26
Assuming 'crv' is equal to CKR_OK
27
Taking false branch
616 fprintf(stderrstderr, "NSC_Initialize failed crv=0x%x\n", (unsigned int)crv);
617 return SECFailure;
618 }
619 }
620
621 /* specific arithmetic tests */
622 if (nist
27.1
'nist' is 1
) {
28
Taking true branch
623 ECTEST_NAMED_GFP("NIST-P256", ECCurve_NIST_P256)if (usefreebl) { printf("Testing %s using freebl implementation...\n"
, "NIST-P256"); rv = ectest_curve_freebl(ECCurve_NIST_P256, iterations
, numThreads, ec_field_GFp); if (rv != SECSuccess) goto cleanup
; printf("... okay.\n"); } if (usepkcs11) { printf("Testing %s using pkcs11 implementation...\n"
, "NIST-P256"); rv = ectest_curve_pkcs11(ECCurve_NIST_P256, iterations
, numThreads); if (rv != SECSuccess) goto cleanup; printf("... okay.\n"
); }
;
29
Taking false branch
30
Taking true branch
31
Calling 'ectest_curve_pkcs11'
624 ECTEST_NAMED_GFP("NIST-P384", ECCurve_NIST_P384)if (usefreebl) { printf("Testing %s using freebl implementation...\n"
, "NIST-P384"); rv = ectest_curve_freebl(ECCurve_NIST_P384, iterations
, numThreads, ec_field_GFp); if (rv != SECSuccess) goto cleanup
; printf("... okay.\n"); } if (usepkcs11) { printf("Testing %s using pkcs11 implementation...\n"
, "NIST-P384"); rv = ectest_curve_pkcs11(ECCurve_NIST_P384, iterations
, numThreads); if (rv != SECSuccess) goto cleanup; printf("... okay.\n"
); }
;
625 ECTEST_NAMED_GFP("NIST-P521", ECCurve_NIST_P521)if (usefreebl) { printf("Testing %s using freebl implementation...\n"
, "NIST-P521"); rv = ectest_curve_freebl(ECCurve_NIST_P521, iterations
, numThreads, ec_field_GFp); if (rv != SECSuccess) goto cleanup
; printf("... okay.\n"); } if (usepkcs11) { printf("Testing %s using pkcs11 implementation...\n"
, "NIST-P521"); rv = ectest_curve_pkcs11(ECCurve_NIST_P521, iterations
, numThreads); if (rv != SECSuccess) goto cleanup; printf("... okay.\n"
); }
;
626 ECTEST_NAMED_CUSTOM("Curve25519", ECCurve25519)if (usefreebl) { printf("Testing %s using freebl implementation...\n"
, "Curve25519"); rv = ectest_curve_freebl(ECCurve25519, iterations
, numThreads, ec_field_plain); if (rv != SECSuccess) goto cleanup
; printf("... okay.\n"); } if (usepkcs11) { printf("Testing %s using pkcs11 implementation...\n"
, "Curve25519"); rv = ectest_curve_pkcs11(ECCurve25519, iterations
, numThreads); if (rv != SECSuccess) goto cleanup; printf("... okay.\n"
); }
;
627 }
628
629cleanup:
630 rv |= SECOID_Shutdown();
631 RNG_RNGShutdown();
632
633 if (rv != SECSuccess) {
634 printf("Error: exiting with error value\n");
635 }
636 return rv;
637}