Bug Summary

File:s/cmd/fipstest/fipstest.c
Warning:line 7602, column 27
The right operand of '<' is a garbage value

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 fipstest.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/fipstest -ffunction-sections -fdata-sections -fcoverage-compilation-dir=/var/lib/jenkins/workspace/nss-scan-build/nss/cmd/fipstest -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 ../../../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 fipstest.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 <stdio.h>
6#include <stdlib.h>
7#include <ctype.h>
8
9#include "secitem.h"
10#include "blapi.h"
11#include "nssutil.h"
12#include "secerr.h"
13#include "secder.h"
14#include "secdig.h"
15#include "secoid.h"
16#include "ec.h"
17#include "hasht.h"
18#include "lowkeyi.h"
19#include "softoken.h"
20#include "pkcs11t.h"
21#define __PASTE(x, y) x##y
22#undef CK_PKCS11_FUNCTION_INFO
23#undef CK_NEED_ARG_LIST
24#define CK_EXTERNextern extern
25#define CK_PKCS11_FUNCTION_INFO(func) \
26 CK_RV __PASTE(NS, func)
27#define CK_NEED_ARG_LIST 1
28#include "pkcs11f.h"
29#undef CK_PKCS11_FUNCTION_INFO
30#undef CK_NEED_ARG_LIST
31#undef __PASTE
32#define SSL3_RANDOM_LENGTH32 32
33
34#if 0
35#include "../../lib/freebl/mpi/mpi.h"
36#endif
37#define MATCH_OPENSSL1 1
38/*#define MATCH_NIST 1 */
39#ifdef MATCH_NIST
40#define VERBOSE_REASON 1
41#endif
42
43extern SECStatus
44EC_DecodeParams(const SECItem *encodedParams, ECParams **ecparams);
45extern SECStatus
46EC_CopyParams(PLArenaPool *arena, ECParams *dstParams,
47 const ECParams *srcParams);
48
49#define ENCRYPT1 1
50#define DECRYPT0 0
51#define BYTEunsigned char unsigned char
52#define DEFAULT_RSA_PUBLIC_EXPONENT0x10001 0x10001
53#define RSA_MAX_TEST_MODULUS_BITS4096 4096
54#define RSA_MAX_TEST_MODULUS_BYTES4096 / 8 RSA_MAX_TEST_MODULUS_BITS4096 / 8
55#define RSA_MAX_TEST_EXPONENT_BYTES8 8
56#define PQG_TEST_SEED_BYTES20 20
57
58SECStatus
59hex_to_byteval(const char *c2, unsigned char *byteval)
60{
61 int i;
62 unsigned char offset;
63 *byteval = 0;
64 for (i = 0; i < 2; i++) {
65 if (c2[i] >= '0' && c2[i] <= '9') {
66 offset = c2[i] - '0';
67 *byteval |= offset << 4 * (1 - i);
68 } else if (c2[i] >= 'a' && c2[i] <= 'f') {
69 offset = c2[i] - 'a';
70 *byteval |= (offset + 10) << 4 * (1 - i);
71 } else if (c2[i] >= 'A' && c2[i] <= 'F') {
72 offset = c2[i] - 'A';
73 *byteval |= (offset + 10) << 4 * (1 - i);
74 } else {
75 return SECFailure;
76 }
77 }
78 return SECSuccess;
79}
80
81SECStatus
82byteval_to_hex(unsigned char byteval, char *c2, char a)
83{
84 int i;
85 unsigned char offset;
86 for (i = 0; i < 2; i++) {
87 offset = (byteval >> 4 * (1 - i)) & 0x0f;
88 if (offset < 10) {
89 c2[i] = '0' + offset;
90 } else {
91 c2[i] = a + offset - 10;
92 }
93 }
94 return SECSuccess;
95}
96
97void
98to_hex_str(char *str, const unsigned char *buf, unsigned int len)
99{
100 unsigned int i;
101 for (i = 0; i < len; i++) {
102 byteval_to_hex(buf[i], &str[2 * i], 'a');
103 }
104 str[2 * len] = '\0';
105}
106
107void
108to_hex_str_cap(char *str, const unsigned char *buf, unsigned int len)
109{
110 unsigned int i;
111 for (i = 0; i < len; i++) {
112 byteval_to_hex(buf[i], &str[2 * i], 'A');
113 }
114 str[2 * len] = '\0';
115}
116
117/*
118 * Convert a string of hex digits (str) to an array (buf) of len bytes.
119 * Return PR_TRUE if the hex string can fit in the byte array. Return
120 * PR_FALSE if the hex string is empty or is too long.
121 */
122PRBool
123from_hex_str(unsigned char *buf, unsigned int len, const char *str)
124{
125 unsigned int nxdigit; /* number of hex digits in str */
126 unsigned int i; /* index into buf */
127 unsigned int j; /* index into str */
128
129 /* count the hex digits */
130 nxdigit = 0;
131 for (nxdigit = 0; isxdigit(str[nxdigit])((*__ctype_b_loc ())[(int) ((str[nxdigit]))] & (unsigned short
int) _ISxdigit)
; nxdigit++) {
132 /* empty body */
133 }
134 if (nxdigit == 0) {
135 return PR_FALSE0;
136 }
137 if (nxdigit > 2 * len) {
138 /*
139 * The input hex string is too long, but we allow it if the
140 * extra digits are leading 0's.
141 */
142 for (j = 0; j < nxdigit - 2 * len; j++) {
143 if (str[j] != '0') {
144 return PR_FALSE0;
145 }
146 }
147 /* skip leading 0's */
148 str += nxdigit - 2 * len;
149 nxdigit = 2 * len;
150 }
151 for (i = 0, j = 0; i < len; i++) {
152 if (2 * i < 2 * len - nxdigit) {
153 /* Handle a short input as if we padded it with leading 0's. */
154 if (2 * i + 1 < 2 * len - nxdigit) {
155 buf[i] = 0;
156 } else {
157 char tmp[2];
158 tmp[0] = '0';
159 tmp[1] = str[j];
160 hex_to_byteval(tmp, &buf[i]);
161 j++;
162 }
163 } else {
164 hex_to_byteval(&str[j], &buf[i]);
165 j += 2;
166 }
167 }
168 return PR_TRUE1;
169}
170
171SECStatus
172tdea_encrypt_buf(
173 int mode,
174 const unsigned char *key,
175 const unsigned char *iv,
176 unsigned char *output, unsigned int *outputlen, unsigned int maxoutputlen,
177 const unsigned char *input, unsigned int inputlen)
178{
179 SECStatus rv = SECFailure;
180 DESContext *cx;
181 unsigned char doublecheck[8 * 20]; /* 1 to 20 blocks */
182 unsigned int doublechecklen = 0;
183
184 cx = DES_CreateContext(key, iv, mode, PR_TRUE1);
185 if (cx == NULL((void*)0)) {
186 goto loser;
187 }
188 rv = DES_Encrypt(cx, output, outputlen, maxoutputlen, input, inputlen);
189 if (rv != SECSuccess) {
190 goto loser;
191 }
192 if (*outputlen != inputlen) {
193 goto loser;
194 }
195 DES_DestroyContext(cx, PR_TRUE1);
196 cx = NULL((void*)0);
197
198 /*
199 * Doublecheck our result by decrypting the ciphertext and
200 * compare the output with the input plaintext.
201 */
202 cx = DES_CreateContext(key, iv, mode, PR_FALSE0);
203 if (cx == NULL((void*)0)) {
204 goto loser;
205 }
206 rv = DES_Decrypt(cx, doublecheck, &doublechecklen, sizeof doublecheck,
207 output, *outputlen);
208 if (rv != SECSuccess) {
209 goto loser;
210 }
211 if (doublechecklen != *outputlen) {
212 goto loser;
213 }
214 DES_DestroyContext(cx, PR_TRUE1);
215 cx = NULL((void*)0);
216 if (memcmp(doublecheck, input, inputlen) != 0) {
217 goto loser;
218 }
219 rv = SECSuccess;
220
221loser:
222 if (cx != NULL((void*)0)) {
223 DES_DestroyContext(cx, PR_TRUE1);
224 }
225 return rv;
226}
227
228SECStatus
229tdea_decrypt_buf(
230 int mode,
231 const unsigned char *key,
232 const unsigned char *iv,
233 unsigned char *output, unsigned int *outputlen, unsigned int maxoutputlen,
234 const unsigned char *input, unsigned int inputlen)
235{
236 SECStatus rv = SECFailure;
237 DESContext *cx;
238 unsigned char doublecheck[8 * 20]; /* 1 to 20 blocks */
239 unsigned int doublechecklen = 0;
240
241 cx = DES_CreateContext(key, iv, mode, PR_FALSE0);
242 if (cx == NULL((void*)0)) {
243 goto loser;
244 }
245 rv = DES_Decrypt(cx, output, outputlen, maxoutputlen,
246 input, inputlen);
247 if (rv != SECSuccess) {
248 goto loser;
249 }
250 if (*outputlen != inputlen) {
251 goto loser;
252 }
253 DES_DestroyContext(cx, PR_TRUE1);
254 cx = NULL((void*)0);
255
256 /*
257 * Doublecheck our result by encrypting the plaintext and
258 * compare the output with the input ciphertext.
259 */
260 cx = DES_CreateContext(key, iv, mode, PR_TRUE1);
261 if (cx == NULL((void*)0)) {
262 goto loser;
263 }
264 rv = DES_Encrypt(cx, doublecheck, &doublechecklen, sizeof doublecheck,
265 output, *outputlen);
266 if (rv != SECSuccess) {
267 goto loser;
268 }
269 if (doublechecklen != *outputlen) {
270 goto loser;
271 }
272 DES_DestroyContext(cx, PR_TRUE1);
273 cx = NULL((void*)0);
274 if (memcmp(doublecheck, input, inputlen) != 0) {
275 goto loser;
276 }
277 rv = SECSuccess;
278
279loser:
280 if (cx != NULL((void*)0)) {
281 DES_DestroyContext(cx, PR_TRUE1);
282 }
283 return rv;
284}
285
286/*
287 * Perform the TDEA Known Answer Test (KAT) or Multi-block Message
288 * Test (MMT) in ECB or CBC mode. The KAT (there are five types)
289 * and MMT have the same structure: given the key and IV (CBC mode
290 * only), encrypt the given plaintext or decrypt the given ciphertext.
291 * So we can handle them the same way.
292 *
293 * reqfn is the pathname of the REQUEST file.
294 *
295 * The output RESPONSE file is written to stdout.
296 */
297void
298tdea_kat_mmt(char *reqfn)
299{
300 char buf[180]; /* holds one line from the input REQUEST file.
301 * needs to be large enough to hold the longest
302 * line "CIPHERTEXT = <180 hex digits>\n".
303 */
304 FILE *req; /* input stream from the REQUEST file */
305 FILE *resp; /* output stream to the RESPONSE file */
306 int i, j;
307 int mode = NSS_DES_EDE32; /* NSS_DES_EDE3 (ECB) or NSS_DES_EDE3_CBC */
308 int crypt = DECRYPT0; /* 1 means encrypt, 0 means decrypt */
309 unsigned char key[24]; /* TDEA 3 key bundle */
310 unsigned int numKeys = 0;
311 unsigned char iv[8]; /* for all modes except ECB */
312 unsigned char plaintext[8 * 20]; /* 1 to 20 blocks */
313 unsigned int plaintextlen;
314 unsigned char ciphertext[8 * 20]; /* 1 to 20 blocks */
315 unsigned int ciphertextlen;
316 SECStatus rv;
317
318 req = fopen(reqfn, "r");
319 resp = stdoutstdout;
320 while (fgets(buf, sizeof buf, req) != NULL((void*)0)) {
321 /* a comment or blank line */
322 if (buf[0] == '#' || buf[0] == '\n') {
323 fputs(buf, resp);
324 continue;
325 }
326 /* [ENCRYPT] or [DECRYPT] */
327 if (buf[0] == '[') {
328 if (strncmp(&buf[1], "ENCRYPT", 7) == 0) {
329 crypt = ENCRYPT1;
330 } else {
331 crypt = DECRYPT0;
332 }
333 fputs(buf, resp);
334 continue;
335 }
336 /* NumKeys */
337 if (strncmp(&buf[0], "NumKeys", 7) == 0) {
338 i = 7;
339 while (isspace(buf[i])((*__ctype_b_loc ())[(int) ((buf[i]))] & (unsigned short int
) _ISspace)
|| buf[i] == '=') {
340 i++;
341 }
342 numKeys = buf[i];
343 fputs(buf, resp);
344 continue;
345 }
346 /* "COUNT = x" begins a new data set */
347 if (strncmp(buf, "COUNT", 5) == 0) {
348 /* mode defaults to ECB, if dataset has IV mode will be set CBC */
349 mode = NSS_DES_EDE32;
350 /* zeroize the variables for the test with this data set */
351 memset(key, 0, sizeof key);
352 memset(iv, 0, sizeof iv);
353 memset(plaintext, 0, sizeof plaintext);
354 plaintextlen = 0;
355 memset(ciphertext, 0, sizeof ciphertext);
356 ciphertextlen = 0;
357 fputs(buf, resp);
358 continue;
359 }
360 if (numKeys == 0) {
361 if (strncmp(buf, "KEYs", 4) == 0) {
362 i = 4;
363 while (isspace(buf[i])((*__ctype_b_loc ())[(int) ((buf[i]))] & (unsigned short int
) _ISspace)
|| buf[i] == '=') {
364 i++;
365 }
366 for (j = 0; isxdigit(buf[i])((*__ctype_b_loc ())[(int) ((buf[i]))] & (unsigned short int
) _ISxdigit)
; i += 2, j++) {
367 hex_to_byteval(&buf[i], &key[j]);
368 key[j + 8] = key[j];
369 key[j + 16] = key[j];
370 }
371 fputs(buf, resp);
372 continue;
373 }
374 } else {
375 /* KEY1 = ... */
376 if (strncmp(buf, "KEY1", 4) == 0) {
377 i = 4;
378 while (isspace(buf[i])((*__ctype_b_loc ())[(int) ((buf[i]))] & (unsigned short int
) _ISspace)
|| buf[i] == '=') {
379 i++;
380 }
381 for (j = 0; isxdigit(buf[i])((*__ctype_b_loc ())[(int) ((buf[i]))] & (unsigned short int
) _ISxdigit)
; i += 2, j++) {
382 hex_to_byteval(&buf[i], &key[j]);
383 }
384 fputs(buf, resp);
385 continue;
386 }
387 /* KEY2 = ... */
388 if (strncmp(buf, "KEY2", 4) == 0) {
389 i = 4;
390 while (isspace(buf[i])((*__ctype_b_loc ())[(int) ((buf[i]))] & (unsigned short int
) _ISspace)
|| buf[i] == '=') {
391 i++;
392 }
393 for (j = 8; isxdigit(buf[i])((*__ctype_b_loc ())[(int) ((buf[i]))] & (unsigned short int
) _ISxdigit)
; i += 2, j++) {
394 hex_to_byteval(&buf[i], &key[j]);
395 }
396 fputs(buf, resp);
397 continue;
398 }
399 /* KEY3 = ... */
400 if (strncmp(buf, "KEY3", 4) == 0) {
401 i = 4;
402 while (isspace(buf[i])((*__ctype_b_loc ())[(int) ((buf[i]))] & (unsigned short int
) _ISspace)
|| buf[i] == '=') {
403 i++;
404 }
405 for (j = 16; isxdigit(buf[i])((*__ctype_b_loc ())[(int) ((buf[i]))] & (unsigned short int
) _ISxdigit)
; i += 2, j++) {
406 hex_to_byteval(&buf[i], &key[j]);
407 }
408 fputs(buf, resp);
409 continue;
410 }
411 }
412
413 /* IV = ... */
414 if (strncmp(buf, "IV", 2) == 0) {
415 mode = NSS_DES_EDE3_CBC3;
416 i = 2;
417 while (isspace(buf[i])((*__ctype_b_loc ())[(int) ((buf[i]))] & (unsigned short int
) _ISspace)
|| buf[i] == '=') {
418 i++;
419 }
420 for (j = 0; j < sizeof iv; i += 2, j++) {
421 hex_to_byteval(&buf[i], &iv[j]);
422 }
423 fputs(buf, resp);
424 continue;
425 }
426
427 /* PLAINTEXT = ... */
428 if (strncmp(buf, "PLAINTEXT", 9) == 0) {
429 /* sanity check */
430 if (crypt != ENCRYPT1) {
431 goto loser;
432 }
433 i = 9;
434 while (isspace(buf[i])((*__ctype_b_loc ())[(int) ((buf[i]))] & (unsigned short int
) _ISspace)
|| buf[i] == '=') {
435 i++;
436 }
437 for (j = 0; isxdigit(buf[i])((*__ctype_b_loc ())[(int) ((buf[i]))] & (unsigned short int
) _ISxdigit)
; i += 2, j++) {
438 hex_to_byteval(&buf[i], &plaintext[j]);
439 }
440 plaintextlen = j;
441 rv = tdea_encrypt_buf(mode, key,
442 (mode == NSS_DES_EDE32) ? NULL((void*)0) : iv,
443 ciphertext, &ciphertextlen, sizeof ciphertext,
444 plaintext, plaintextlen);
445 if (rv != SECSuccess) {
446 goto loser;
447 }
448
449 fputs(buf, resp);
450 fputs("CIPHERTEXT = ", resp);
451 to_hex_str(buf, ciphertext, ciphertextlen);
452 fputs(buf, resp);
453 fputc('\n', resp);
454 continue;
455 }
456 /* CIPHERTEXT = ... */
457 if (strncmp(buf, "CIPHERTEXT", 10) == 0) {
458 /* sanity check */
459 if (crypt != DECRYPT0) {
460 goto loser;
461 }
462
463 i = 10;
464 while (isspace(buf[i])((*__ctype_b_loc ())[(int) ((buf[i]))] & (unsigned short int
) _ISspace)
|| buf[i] == '=') {
465 i++;
466 }
467 for (j = 0; isxdigit(buf[i])((*__ctype_b_loc ())[(int) ((buf[i]))] & (unsigned short int
) _ISxdigit)
; i += 2, j++) {
468 hex_to_byteval(&buf[i], &ciphertext[j]);
469 }
470 ciphertextlen = j;
471
472 rv = tdea_decrypt_buf(mode, key,
473 (mode == NSS_DES_EDE32) ? NULL((void*)0) : iv,
474 plaintext, &plaintextlen, sizeof plaintext,
475 ciphertext, ciphertextlen);
476 if (rv != SECSuccess) {
477 goto loser;
478 }
479
480 fputs(buf, resp);
481 fputs("PLAINTEXT = ", resp);
482 to_hex_str(buf, plaintext, plaintextlen);
483 fputs(buf, resp);
484 fputc('\n', resp);
485 continue;
486 }
487 }
488
489loser:
490 fclose(req);
491}
492
493/*
494* Set the parity bit for the given byte
495*/
496BYTEunsigned char
497odd_parity(BYTEunsigned char in)
498{
499 BYTEunsigned char out = in;
500 in ^= in >> 4;
501 in ^= in >> 2;
502 in ^= in >> 1;
503 return (BYTEunsigned char)(out ^ !(in & 1));
504}
505
506/*
507 * Generate Keys [i+1] from Key[i], PT/CT[j-2], PT/CT[j-1], and PT/CT[j]
508 * for TDEA Monte Carlo Test (MCT) in ECB and CBC modes.
509 */
510void
511tdea_mct_next_keys(unsigned char *key,
512 const unsigned char *text_2, const unsigned char *text_1,
513 const unsigned char *text, unsigned int numKeys)
514{
515 int k;
516
517 /* key1[i+1] = key1[i] xor PT/CT[j] */
518 for (k = 0; k < 8; k++) {
519 key[k] ^= text[k];
520 }
521 /* key2 */
522 if (numKeys == 2 || numKeys == 3) {
523 /* key2 independent */
524 for (k = 8; k < 16; k++) {
525 /* key2[i+1] = KEY2[i] xor PT/CT[j-1] */
526 key[k] ^= text_1[k - 8];
527 }
528 } else {
529 /* key2 == key 1 */
530 for (k = 8; k < 16; k++) {
531 /* key2[i+1] = KEY2[i] xor PT/CT[j] */
532 key[k] = key[k - 8];
533 }
534 }
535 /* key3 */
536 if (numKeys == 1 || numKeys == 2) {
537 /* key3 == key 1 */
538 for (k = 16; k < 24; k++) {
539 /* key3[i+1] = KEY3[i] xor PT/CT[j] */
540 key[k] = key[k - 16];
541 }
542 } else {
543 /* key3 independent */
544 for (k = 16; k < 24; k++) {
545 /* key3[i+1] = KEY3[i] xor PT/CT[j-2] */
546 key[k] ^= text_2[k - 16];
547 }
548 }
549 /* set the parity bits */
550 for (k = 0; k < 24; k++) {
551 key[k] = odd_parity(key[k]);
552 }
553}
554
555/*
556 * Perform the Monte Carlo Test
557 *
558 * mode = NSS_DES_EDE3 or NSS_DES_EDE3_CBC
559 * crypt = ENCRYPT || DECRYPT
560 * inputtext = plaintext or Cyphertext depending on the value of crypt
561 * inputlength is expected to be size 8 bytes
562 * iv = needs to be set for NSS_DES_EDE3_CBC mode
563 * resp = is the output response file.
564 */
565void
566tdea_mct_test(int mode, unsigned char *key, unsigned int numKeys,
567 unsigned int crypt, unsigned char *inputtext,
568 unsigned int inputlength, unsigned char *iv, FILE *resp)
569{
570
571 int i, j;
572 unsigned char outputtext_1[8]; /* PT/CT[j-1] */
573 unsigned char outputtext_2[8]; /* PT/CT[j-2] */
574 char buf[80]; /* holds one line from the input REQUEST file. */
575 unsigned int outputlen;
576 unsigned char outputtext[8];
577
578 SECStatus rv;
579
580 if (mode == NSS_DES_EDE32 && iv != NULL((void*)0)) {
581 printf("IV must be NULL for NSS_DES_EDE3 mode");
582 goto loser;
583 } else if (mode == NSS_DES_EDE3_CBC3 && iv == NULL((void*)0)) {
584 printf("IV must not be NULL for NSS_DES_EDE3_CBC mode");
585 goto loser;
586 }
587
588 /* loop 400 times */
589 for (i = 0; i < 400; i++) {
590 /* if i == 0 CV[0] = IV not necessary */
591 /* record the count and key values and plainText */
592 snprintf(buf, sizeof(buf), "COUNT = %d\n", i);
593 fputs(buf, resp);
594 /* Output KEY1[i] */
595 fputs("KEY1 = ", resp);
596 to_hex_str(buf, key, 8);
597 fputs(buf, resp);
598 fputc('\n', resp);
599 /* Output KEY2[i] */
600 fputs("KEY2 = ", resp);
601 to_hex_str(buf, &key[8], 8);
602 fputs(buf, resp);
603 fputc('\n', resp);
604 /* Output KEY3[i] */
605 fputs("KEY3 = ", resp);
606 to_hex_str(buf, &key[16], 8);
607 fputs(buf, resp);
608 fputc('\n', resp);
609 if (mode == NSS_DES_EDE3_CBC3) {
610 /* Output CV[i] */
611 fputs("IV = ", resp);
612 to_hex_str(buf, iv, 8);
613 fputs(buf, resp);
614 fputc('\n', resp);
615 }
616 if (crypt == ENCRYPT1) {
617 /* Output PT[0] */
618 fputs("PLAINTEXT = ", resp);
619 } else {
620 /* Output CT[0] */
621 fputs("CIPHERTEXT = ", resp);
622 }
623
624 to_hex_str(buf, inputtext, inputlength);
625 fputs(buf, resp);
626 fputc('\n', resp);
627
628 /* loop 10,000 times */
629 for (j = 0; j < 10000; j++) {
630
631 outputlen = 0;
632 if (crypt == ENCRYPT1) {
633 /* inputtext == ciphertext outputtext == plaintext*/
634 rv = tdea_encrypt_buf(mode, key,
635 (mode ==
636 NSS_DES_EDE32)
637 ? NULL((void*)0)
638 : iv,
639 outputtext, &outputlen, 8,
640 inputtext, 8);
641 } else {
642 /* inputtext == plaintext outputtext == ciphertext */
643 rv = tdea_decrypt_buf(mode, key,
644 (mode ==
645 NSS_DES_EDE32)
646 ? NULL((void*)0)
647 : iv,
648 outputtext, &outputlen, 8,
649 inputtext, 8);
650 }
651
652 if (rv != SECSuccess) {
653 goto loser;
654 }
655 if (outputlen != inputlength) {
656 goto loser;
657 }
658
659 if (mode == NSS_DES_EDE3_CBC3) {
660 if (crypt == ENCRYPT1) {
661 if (j == 0) {
662 /*P[j+1] = CV[0] */
663 memcpy(inputtext, iv, 8);
664 } else {
665 /* p[j+1] = C[j-1] */
666 memcpy(inputtext, outputtext_1, 8);
667 }
668 /* CV[j+1] = C[j] */
669 memcpy(iv, outputtext, 8);
670 if (j != 9999) {
671 /* save C[j-1] */
672 memcpy(outputtext_1, outputtext, 8);
673 }
674 } else { /* DECRYPT */
675 /* CV[j+1] = C[j] */
676 memcpy(iv, inputtext, 8);
677 /* C[j+1] = P[j] */
678 memcpy(inputtext, outputtext, 8);
679 }
680 } else {
681 /* ECB mode PT/CT[j+1] = CT/PT[j] */
682 memcpy(inputtext, outputtext, 8);
683 }
684
685 /* Save PT/CT[j-2] and PT/CT[j-1] */
686 if (j == 9997)
687 memcpy(outputtext_2, outputtext, 8);
688 if (j == 9998)
689 memcpy(outputtext_1, outputtext, 8);
690 /* done at the end of the for(j) loop */
691 }
692
693 if (crypt == ENCRYPT1) {
694 /* Output CT[j] */
695 fputs("CIPHERTEXT = ", resp);
696 } else {
697 /* Output PT[j] */
698 fputs("PLAINTEXT = ", resp);
699 }
700 to_hex_str(buf, outputtext, 8);
701 fputs(buf, resp);
702 fputc('\n', resp);
703
704 /* Key[i+1] = Key[i] xor ... outputtext_2 == PT/CT[j-2]
705 * outputtext_1 == PT/CT[j-1] outputtext == PT/CT[j]
706 */
707 tdea_mct_next_keys(key, outputtext_2,
708 outputtext_1, outputtext, numKeys);
709
710 if (mode == NSS_DES_EDE3_CBC3) {
711 /* taken care of in the j=9999 iteration */
712 if (crypt == ENCRYPT1) {
713 /* P[i] = C[j-1] */
714 /* CV[i] = C[j] */
715 } else {
716 /* taken care of in the j=9999 iteration */
717 /* CV[i] = C[j] */
718 /* C[i] = P[j] */
719 }
720 } else {
721 /* ECB PT/CT[i] = PT/CT[j] */
722 memcpy(inputtext, outputtext, 8);
723 }
724 /* done at the end of the for(i) loop */
725 fputc('\n', resp);
726 }
727
728loser:
729 return;
730}
731
732/*
733 * Perform the TDEA Monte Carlo Test (MCT) in ECB/CBC modes.
734 * by gathering the input from the request file, and then
735 * calling tdea_mct_test.
736 *
737 * reqfn is the pathname of the input REQUEST file.
738 *
739 * The output RESPONSE file is written to stdout.
740 */
741void
742tdea_mct(int mode, char *reqfn)
743{
744 int i, j;
745 char buf[80]; /* holds one line from the input REQUEST file. */
746 FILE *req; /* input stream from the REQUEST file */
747 FILE *resp; /* output stream to the RESPONSE file */
748 unsigned int crypt = 0; /* 1 means encrypt, 0 means decrypt */
749 unsigned char key[24]; /* TDEA 3 key bundle */
750 unsigned int numKeys = 0;
751 unsigned char plaintext[8]; /* PT[j] */
752 unsigned char ciphertext[8]; /* CT[j] */
753 unsigned char iv[8];
754
755 /* zeroize the variables for the test with this data set */
756 memset(key, 0, sizeof key);
757 memset(plaintext, 0, sizeof plaintext);
758 memset(ciphertext, 0, sizeof ciphertext);
759 memset(iv, 0, sizeof iv);
760
761 req = fopen(reqfn, "r");
762 resp = stdoutstdout;
763 while (fgets(buf, sizeof buf, req) != NULL((void*)0)) {
764 /* a comment or blank line */
765 if (buf[0] == '#' || buf[0] == '\n') {
766 fputs(buf, resp);
767 continue;
768 }
769 /* [ENCRYPT] or [DECRYPT] */
770 if (buf[0] == '[') {
771 if (strncmp(&buf[1], "ENCRYPT", 7) == 0) {
772 crypt = ENCRYPT1;
773 } else {
774 crypt = DECRYPT0;
775 }
776 fputs(buf, resp);
777 continue;
778 }
779 /* NumKeys */
780 if (strncmp(&buf[0], "NumKeys", 7) == 0) {
781 i = 7;
782 while (isspace(buf[i])((*__ctype_b_loc ())[(int) ((buf[i]))] & (unsigned short int
) _ISspace)
|| buf[i] == '=') {
783 i++;
784 }
785 numKeys = atoi(&buf[i]);
786 continue;
787 }
788 /* KEY1 = ... */
789 if (strncmp(buf, "KEY1", 4) == 0) {
790 i = 4;
791 while (isspace(buf[i])((*__ctype_b_loc ())[(int) ((buf[i]))] & (unsigned short int
) _ISspace)
|| buf[i] == '=') {
792 i++;
793 }
794 for (j = 0; isxdigit(buf[i])((*__ctype_b_loc ())[(int) ((buf[i]))] & (unsigned short int
) _ISxdigit)
; i += 2, j++) {
795 hex_to_byteval(&buf[i], &key[j]);
796 }
797 continue;
798 }
799 /* KEY2 = ... */
800 if (strncmp(buf, "KEY2", 4) == 0) {
801 i = 4;
802 while (isspace(buf[i])((*__ctype_b_loc ())[(int) ((buf[i]))] & (unsigned short int
) _ISspace)
|| buf[i] == '=') {
803 i++;
804 }
805 for (j = 8; isxdigit(buf[i])((*__ctype_b_loc ())[(int) ((buf[i]))] & (unsigned short int
) _ISxdigit)
; i += 2, j++) {
806 hex_to_byteval(&buf[i], &key[j]);
807 }
808 continue;
809 }
810 /* KEY3 = ... */
811 if (strncmp(buf, "KEY3", 4) == 0) {
812 i = 4;
813 while (isspace(buf[i])((*__ctype_b_loc ())[(int) ((buf[i]))] & (unsigned short int
) _ISspace)
|| buf[i] == '=') {
814 i++;
815 }
816 for (j = 16; isxdigit(buf[i])((*__ctype_b_loc ())[(int) ((buf[i]))] & (unsigned short int
) _ISxdigit)
; i += 2, j++) {
817 hex_to_byteval(&buf[i], &key[j]);
818 }
819 continue;
820 }
821
822 /* IV = ... */
823 if (strncmp(buf, "IV", 2) == 0) {
824 i = 2;
825 while (isspace(buf[i])((*__ctype_b_loc ())[(int) ((buf[i]))] & (unsigned short int
) _ISspace)
|| buf[i] == '=') {
826 i++;
827 }
828 for (j = 0; j < sizeof iv; i += 2, j++) {
829 hex_to_byteval(&buf[i], &iv[j]);
830 }
831 continue;
832 }
833
834 /* PLAINTEXT = ... */
835 if (strncmp(buf, "PLAINTEXT", 9) == 0) {
836
837 /* sanity check */
838 if (crypt != ENCRYPT1) {
839 goto loser;
840 }
841 /* PT[0] = PT */
842 i = 9;
843 while (isspace(buf[i])((*__ctype_b_loc ())[(int) ((buf[i]))] & (unsigned short int
) _ISspace)
|| buf[i] == '=') {
844 i++;
845 }
846 for (j = 0; j < sizeof plaintext; i += 2, j++) {
847 hex_to_byteval(&buf[i], &plaintext[j]);
848 }
849
850 /* do the Monte Carlo test */
851 if (mode == NSS_DES_EDE32) {
852 tdea_mct_test(NSS_DES_EDE32, key, numKeys, crypt, plaintext, sizeof plaintext, NULL((void*)0), resp);
853 } else {
854 tdea_mct_test(NSS_DES_EDE3_CBC3, key, numKeys, crypt, plaintext, sizeof plaintext, iv, resp);
855 }
856 continue;
857 }
858 /* CIPHERTEXT = ... */
859 if (strncmp(buf, "CIPHERTEXT", 10) == 0) {
860 /* sanity check */
861 if (crypt != DECRYPT0) {
862 goto loser;
863 }
864 /* CT[0] = CT */
865 i = 10;
866 while (isspace(buf[i])((*__ctype_b_loc ())[(int) ((buf[i]))] & (unsigned short int
) _ISspace)
|| buf[i] == '=') {
867 i++;
868 }
869 for (j = 0; isxdigit(buf[i])((*__ctype_b_loc ())[(int) ((buf[i]))] & (unsigned short int
) _ISxdigit)
; i += 2, j++) {
870 hex_to_byteval(&buf[i], &ciphertext[j]);
871 }
872
873 /* do the Monte Carlo test */
874 if (mode == NSS_DES_EDE32) {
875 tdea_mct_test(NSS_DES_EDE32, key, numKeys, crypt, ciphertext, sizeof ciphertext, NULL((void*)0), resp);
876 } else {
877 tdea_mct_test(NSS_DES_EDE3_CBC3, key, numKeys, crypt, ciphertext, sizeof ciphertext, iv, resp);
878 }
879 continue;
880 }
881 }
882
883loser:
884 fclose(req);
885}
886
887SECStatus
888aes_encrypt_buf(
889 int mode,
890 const unsigned char *key, unsigned int keysize,
891 const unsigned char *iv,
892 unsigned char *output, unsigned int *outputlen, unsigned int maxoutputlen,
893 const unsigned char *input, unsigned int inputlen)
894{
895 SECStatus rv = SECFailure;
896 AESContext *cx;
897 unsigned char doublecheck[10 * 16]; /* 1 to 10 blocks */
898 unsigned int doublechecklen = 0;
899
900 cx = AES_CreateContext(key, iv, mode, PR_TRUE1, keysize, 16);
901 if (cx == NULL((void*)0)) {
902 goto loser;
903 }
904 rv = AES_Encrypt(cx, output, outputlen, maxoutputlen, input, inputlen);
905 if (rv != SECSuccess) {
906 goto loser;
907 }
908 if (*outputlen != inputlen) {
909 goto loser;
910 }
911 AES_DestroyContext(cx, PR_TRUE1);
912 cx = NULL((void*)0);
913
914 /*
915 * Doublecheck our result by decrypting the ciphertext and
916 * compare the output with the input plaintext.
917 */
918 cx = AES_CreateContext(key, iv, mode, PR_FALSE0, keysize, 16);
919 if (cx == NULL((void*)0)) {
920 goto loser;
921 }
922 rv = AES_Decrypt(cx, doublecheck, &doublechecklen, sizeof doublecheck,
923 output, *outputlen);
924 if (rv != SECSuccess) {
925 goto loser;
926 }
927 if (doublechecklen != *outputlen) {
928 goto loser;
929 }
930 AES_DestroyContext(cx, PR_TRUE1);
931 cx = NULL((void*)0);
932 if (memcmp(doublecheck, input, inputlen) != 0) {
933 goto loser;
934 }
935 rv = SECSuccess;
936
937loser:
938 if (cx != NULL((void*)0)) {
939 AES_DestroyContext(cx, PR_TRUE1);
940 }
941 return rv;
942}
943
944SECStatus
945aes_decrypt_buf(
946 int mode,
947 const unsigned char *key, unsigned int keysize,
948 const unsigned char *iv,
949 unsigned char *output, unsigned int *outputlen, unsigned int maxoutputlen,
950 const unsigned char *input, unsigned int inputlen)
951{
952 SECStatus rv = SECFailure;
953 AESContext *cx;
954 unsigned char doublecheck[10 * 16]; /* 1 to 10 blocks */
955 unsigned int doublechecklen = 0;
956
957 cx = AES_CreateContext(key, iv, mode, PR_FALSE0, keysize, 16);
958 if (cx == NULL((void*)0)) {
959 goto loser;
960 }
961 rv = AES_Decrypt(cx, output, outputlen, maxoutputlen,
962 input, inputlen);
963 if (rv != SECSuccess) {
964 goto loser;
965 }
966 if (*outputlen != inputlen) {
967 goto loser;
968 }
969 AES_DestroyContext(cx, PR_TRUE1);
970 cx = NULL((void*)0);
971
972 /*
973 * Doublecheck our result by encrypting the plaintext and
974 * compare the output with the input ciphertext.
975 */
976 cx = AES_CreateContext(key, iv, mode, PR_TRUE1, keysize, 16);
977 if (cx == NULL((void*)0)) {
978 goto loser;
979 }
980 rv = AES_Encrypt(cx, doublecheck, &doublechecklen, sizeof doublecheck,
981 output, *outputlen);
982 if (rv != SECSuccess) {
983 goto loser;
984 }
985 if (doublechecklen != *outputlen) {
986 goto loser;
987 }
988 AES_DestroyContext(cx, PR_TRUE1);
989 cx = NULL((void*)0);
990 if (memcmp(doublecheck, input, inputlen) != 0) {
991 goto loser;
992 }
993 rv = SECSuccess;
994
995loser:
996 if (cx != NULL((void*)0)) {
997 AES_DestroyContext(cx, PR_TRUE1);
998 }
999 return rv;
1000}
1001/*
1002 * Perform the AES GCM tests.
1003 *
1004 * reqfn is the pathname of the REQUEST file.
1005 *
1006 * The output RESPONSE file is written to stdout.
1007 */
1008void
1009aes_gcm(char *reqfn, int encrypt)
1010{
1011 char buf[512]; /* holds one line from the input REQUEST file.
1012 * needs to be large enough to hold the longest
1013 * line "CIPHERTEXT = <320 hex digits>\n".
1014 */
1015 FILE *aesreq; /* input stream from the REQUEST file */
1016 FILE *aesresp; /* output stream to the RESPONSE file */
1017 int i, j;
1018 unsigned char key[32]; /* 128, 192, or 256 bits */
1019 unsigned int keysize = 0;
1020 unsigned char iv[128]; /* handle large gcm IV's */
1021 unsigned char plaintext[10 * 16]; /* 1 to 10 blocks */
1022 unsigned int plaintextlen;
1023 unsigned char ciphertext[11 * 16]; /* 1 to 10 blocks + tag */
1024 unsigned int ciphertextlen;
1025 unsigned char aad[11 * 16]; /* 1 to 10 blocks + tag */
1026 unsigned int aadlen = 0;
1027 unsigned int tagbits;
1028 unsigned int taglen = 0;
1029 unsigned int ivlen;
1030 CK_NSS_GCM_PARAMS params;
1031 SECStatus rv;
1032
1033 aesreq = fopen(reqfn, "r");
1034 aesresp = stdoutstdout;
1035 while (fgets(buf, sizeof buf, aesreq) != NULL((void*)0)) {
1036 /* a comment or blank line */
1037 if (buf[0] == '#' || buf[0] == '\n') {
1038 fputs(buf, aesresp);
1039 continue;
1040 }
1041 /* [ENCRYPT] or [DECRYPT] */
1042 if (buf[0] == '[') {
1043 if (strncmp(buf, "[Taglen", 7) == 0) {
1044 if (sscanf(buf, "[Taglen = %d]", &tagbits) != 1) {
1045 goto loser;
1046 }
1047 taglen = tagbits / 8;
1048 }
1049 if (strncmp(buf, "[IVlen", 6) == 0) {
1050 if (sscanf(buf, "[IVlen = %d]", &ivlen) != 1) {
1051 goto loser;
1052 }
1053 ivlen = ivlen / 8;
1054 }
1055 fputs(buf, aesresp);
1056 continue;
1057 }
1058 /* "COUNT = x" begins a new data set */
1059 if (strncmp(buf, "Count", 5) == 0) {
1060 /* zeroize the variables for the test with this data set */
1061 memset(key, 0, sizeof key);
1062 keysize = 0;
1063 memset(iv, 0, sizeof iv);
1064 memset(plaintext, 0, sizeof plaintext);
1065 plaintextlen = 0;
1066 memset(ciphertext, 0, sizeof ciphertext);
1067 ciphertextlen = 0;
1068 fputs(buf, aesresp);
1069 continue;
1070 }
1071 /* KEY = ... */
1072 if (strncmp(buf, "Key", 3) == 0) {
1073 i = 3;
1074 while (isspace(buf[i])((*__ctype_b_loc ())[(int) ((buf[i]))] & (unsigned short int
) _ISspace)
|| buf[i] == '=') {
1075 i++;
1076 }
1077 for (j = 0; isxdigit(buf[i])((*__ctype_b_loc ())[(int) ((buf[i]))] & (unsigned short int
) _ISxdigit)
; i += 2, j++) {
1078 hex_to_byteval(&buf[i], &key[j]);
1079 }
1080 keysize = j;
1081 fputs(buf, aesresp);
1082 continue;
1083 }
1084 /* IV = ... */
1085 if (strncmp(buf, "IV", 2) == 0) {
1086 i = 2;
1087 while (isspace(buf[i])((*__ctype_b_loc ())[(int) ((buf[i]))] & (unsigned short int
) _ISspace)
|| buf[i] == '=') {
1088 i++;
1089 }
1090 for (j = 0; j < sizeof iv; i += 2, j++) {
1091 hex_to_byteval(&buf[i], &iv[j]);
1092 }
1093 fputs(buf, aesresp);
1094 continue;
1095 }
1096 /* PLAINTEXT = ... */
1097 if (strncmp(buf, "PT", 2) == 0) {
1098 /* sanity check */
1099 if (!encrypt) {
1100 goto loser;
1101 }
1102
1103 i = 2;
1104 while (isspace(buf[i])((*__ctype_b_loc ())[(int) ((buf[i]))] & (unsigned short int
) _ISspace)
|| buf[i] == '=') {
1105 i++;
1106 }
1107 for (j = 0; isxdigit(buf[i])((*__ctype_b_loc ())[(int) ((buf[i]))] & (unsigned short int
) _ISxdigit)
; i += 2, j++) {
1108 hex_to_byteval(&buf[i], &plaintext[j]);
1109 }
1110 plaintextlen = j;
1111 fputs(buf, aesresp);
1112 continue;
1113 }
1114 /* CIPHERTEXT = ... */
1115 if (strncmp(buf, "CT", 2) == 0) {
1116 /* sanity check */
1117 if (encrypt) {
1118 goto loser;
1119 }
1120
1121 i = 2;
1122 while (isspace(buf[i])((*__ctype_b_loc ())[(int) ((buf[i]))] & (unsigned short int
) _ISspace)
|| buf[i] == '=') {
1123 i++;
1124 }
1125 for (j = 0; isxdigit(buf[i])((*__ctype_b_loc ())[(int) ((buf[i]))] & (unsigned short int
) _ISxdigit)
; i += 2, j++) {
1126 hex_to_byteval(&buf[i], &ciphertext[j]);
1127 }
1128 ciphertextlen = j;
1129 fputs(buf, aesresp);
1130 continue;
1131 }
1132 if (strncmp(buf, "AAD", 3) == 0) {
1133 i = 3;
1134 while (isspace(buf[i])((*__ctype_b_loc ())[(int) ((buf[i]))] & (unsigned short int
) _ISspace)
|| buf[i] == '=') {
1135 i++;
1136 }
1137 for (j = 0; isxdigit(buf[i])((*__ctype_b_loc ())[(int) ((buf[i]))] & (unsigned short int
) _ISxdigit)
; i += 2, j++) {
1138 hex_to_byteval(&buf[i], &aad[j]);
1139 }
1140 aadlen = j;
1141 fputs(buf, aesresp);
1142 if (encrypt) {
1143 if (encrypt == 2) {
1144 rv = RNG_GenerateGlobalRandomBytes(iv, ivlen);
1145 if (rv != SECSuccess) {
1146 goto loser;
1147 }
1148 }
1149 params.pIv = iv;
1150 params.ulIvLen = ivlen;
1151 params.pAAD = aad;
1152 params.ulAADLen = aadlen;
1153 params.ulTagBits = tagbits;
1154 rv = aes_encrypt_buf(NSS_AES_GCM4, key, keysize,
1155 (unsigned char *)&params,
1156 ciphertext, &ciphertextlen, sizeof ciphertext,
1157 plaintext, plaintextlen);
1158 if (rv != SECSuccess) {
1159 goto loser;
1160 }
1161
1162 if (encrypt == 2) {
1163 fputs("IV = ", aesresp);
1164 to_hex_str(buf, iv, ivlen);
1165 fputs(buf, aesresp);
1166 fputc('\n', aesresp);
1167 }
1168 fputs("CT = ", aesresp);
1169 j = ciphertextlen - taglen;
1170 to_hex_str(buf, ciphertext, j);
1171 fputs(buf, aesresp);
1172 fputs("\nTag = ", aesresp);
1173 to_hex_str(buf, ciphertext + j, taglen);
1174 fputs(buf, aesresp);
1175 fputc('\n', aesresp);
1176 }
1177 continue;
1178 }
1179 if (strncmp(buf, "Tag", 3) == 0) {
1180 /* sanity check */
1181 if (encrypt) {
1182 goto loser;
1183 }
1184
1185 i = 3;
1186 while (isspace(buf[i])((*__ctype_b_loc ())[(int) ((buf[i]))] & (unsigned short int
) _ISspace)
|| buf[i] == '=') {
1187 i++;
1188 }
1189 for (j = 0; isxdigit(buf[i])((*__ctype_b_loc ())[(int) ((buf[i]))] & (unsigned short int
) _ISxdigit)
; i += 2, j++) {
1190 hex_to_byteval(&buf[i], &ciphertext[j + ciphertextlen]);
1191 }
1192 ciphertextlen += j;
1193 params.pIv = iv;
1194 params.ulIvLen = ivlen;
1195 params.pAAD = aad;
1196 params.ulAADLen = aadlen;
1197 params.ulTagBits = tagbits;
1198 rv = aes_decrypt_buf(NSS_AES_GCM4, key, keysize,
1199 (unsigned char *)&params,
1200 plaintext, &plaintextlen, sizeof plaintext,
1201 ciphertext, ciphertextlen);
1202 fputs(buf, aesresp);
1203 if (rv != SECSuccess) {
1204 fprintf(aesresp, "FAIL\n");
1205 } else {
1206 fputs("PT = ", aesresp);
1207 to_hex_str(buf, plaintext, plaintextlen);
1208 fputs(buf, aesresp);
1209 fputc('\n', aesresp);
1210 }
1211 continue;
1212 }
1213 }
1214loser:
1215 fclose(aesreq);
1216}
1217
1218/*
1219 * Perform the AES Known Answer Test (KAT) or Multi-block Message
1220 * Test (MMT) in ECB or CBC mode. The KAT (there are four types)
1221 * and MMT have the same structure: given the key and IV (CBC mode
1222 * only), encrypt the given plaintext or decrypt the given ciphertext.
1223 * So we can handle them the same way.
1224 *
1225 * reqfn is the pathname of the REQUEST file.
1226 *
1227 * The output RESPONSE file is written to stdout.
1228 */
1229void
1230aes_kat_mmt(char *reqfn)
1231{
1232 char buf[512]; /* holds one line from the input REQUEST file.
1233 * needs to be large enough to hold the longest
1234 * line "CIPHERTEXT = <320 hex digits>\n".
1235 */
1236 FILE *aesreq; /* input stream from the REQUEST file */
1237 FILE *aesresp; /* output stream to the RESPONSE file */
1238 int i, j;
1239 int mode = NSS_AES0; /* NSS_AES (ECB) or NSS_AES_CBC */
1240 int encrypt = 0; /* 1 means encrypt, 0 means decrypt */
1241 unsigned char key[32]; /* 128, 192, or 256 bits */
1242 unsigned int keysize = 0;
1243 unsigned char iv[16]; /* for all modes except ECB */
1244 unsigned char plaintext[10 * 16]; /* 1 to 10 blocks */
1245 unsigned int plaintextlen;
1246 unsigned char ciphertext[10 * 16]; /* 1 to 10 blocks */
1247 unsigned int ciphertextlen;
1248 SECStatus rv;
1249
1250 aesreq = fopen(reqfn, "r");
1251 aesresp = stdoutstdout;
1252 while (fgets(buf, sizeof buf, aesreq) != NULL((void*)0)) {
1253 /* a comment or blank line */
1254 if (buf[0] == '#' || buf[0] == '\n') {
1255 fputs(buf, aesresp);
1256 continue;
1257 }
1258 /* [ENCRYPT] or [DECRYPT] */
1259 if (buf[0] == '[') {
1260 if (strncmp(&buf[1], "ENCRYPT", 7) == 0) {
1261 encrypt = 1;
1262 } else {
1263 encrypt = 0;
1264 }
1265 fputs(buf, aesresp);
1266 continue;
1267 }
1268 /* "COUNT = x" begins a new data set */
1269 if (strncmp(buf, "COUNT", 5) == 0) {
1270 mode = NSS_AES0;
1271 /* zeroize the variables for the test with this data set */
1272 memset(key, 0, sizeof key);
1273 keysize = 0;
1274 memset(iv, 0, sizeof iv);
1275 memset(plaintext, 0, sizeof plaintext);
1276 plaintextlen = 0;
1277 memset(ciphertext, 0, sizeof ciphertext);
1278 ciphertextlen = 0;
1279 fputs(buf, aesresp);
1280 continue;
1281 }
1282 /* KEY = ... */
1283 if (strncmp(buf, "KEY", 3) == 0) {
1284 i = 3;
1285 while (isspace(buf[i])((*__ctype_b_loc ())[(int) ((buf[i]))] & (unsigned short int
) _ISspace)
|| buf[i] == '=') {
1286 i++;
1287 }
1288 for (j = 0; isxdigit(buf[i])((*__ctype_b_loc ())[(int) ((buf[i]))] & (unsigned short int
) _ISxdigit)
; i += 2, j++) {
1289 hex_to_byteval(&buf[i], &key[j]);
1290 }
1291 keysize = j;
1292 fputs(buf, aesresp);
1293 continue;
1294 }
1295 /* IV = ... */
1296 if (strncmp(buf, "IV", 2) == 0) {
1297 mode = NSS_AES_CBC1;
1298 i = 2;
1299 while (isspace(buf[i])((*__ctype_b_loc ())[(int) ((buf[i]))] & (unsigned short int
) _ISspace)
|| buf[i] == '=') {
1300 i++;
1301 }
1302 for (j = 0; j < sizeof iv; i += 2, j++) {
1303 hex_to_byteval(&buf[i], &iv[j]);
1304 }
1305 fputs(buf, aesresp);
1306 continue;
1307 }
1308 /* PLAINTEXT = ... */
1309 if (strncmp(buf, "PLAINTEXT", 9) == 0) {
1310 /* sanity check */
1311 if (!encrypt) {
1312 goto loser;
1313 }
1314
1315 i = 9;
1316 while (isspace(buf[i])((*__ctype_b_loc ())[(int) ((buf[i]))] & (unsigned short int
) _ISspace)
|| buf[i] == '=') {
1317 i++;
1318 }
1319 for (j = 0; isxdigit(buf[i])((*__ctype_b_loc ())[(int) ((buf[i]))] & (unsigned short int
) _ISxdigit)
; i += 2, j++) {
1320 hex_to_byteval(&buf[i], &plaintext[j]);
1321 }
1322 plaintextlen = j;
1323
1324 rv = aes_encrypt_buf(mode, key, keysize,
1325 (mode ==
1326 NSS_AES0)
1327 ? NULL((void*)0)
1328 : iv,
1329 ciphertext, &ciphertextlen, sizeof ciphertext,
1330 plaintext, plaintextlen);
1331 if (rv != SECSuccess) {
1332 goto loser;
1333 }
1334
1335 fputs(buf, aesresp);
1336 fputs("CIPHERTEXT = ", aesresp);
1337 to_hex_str(buf, ciphertext, ciphertextlen);
1338 fputs(buf, aesresp);
1339 fputc('\n', aesresp);
1340 continue;
1341 }
1342 /* CIPHERTEXT = ... */
1343 if (strncmp(buf, "CIPHERTEXT", 10) == 0) {
1344 /* sanity check */
1345 if (encrypt) {
1346 goto loser;
1347 }
1348
1349 i = 10;
1350 while (isspace(buf[i])((*__ctype_b_loc ())[(int) ((buf[i]))] & (unsigned short int
) _ISspace)
|| buf[i] == '=') {
1351 i++;
1352 }
1353 for (j = 0; isxdigit(buf[i])((*__ctype_b_loc ())[(int) ((buf[i]))] & (unsigned short int
) _ISxdigit)
; i += 2, j++) {
1354 hex_to_byteval(&buf[i], &ciphertext[j]);
1355 }
1356 ciphertextlen = j;
1357
1358 rv = aes_decrypt_buf(mode, key, keysize,
1359 (mode ==
1360 NSS_AES0)
1361 ? NULL((void*)0)
1362 : iv,
1363 plaintext, &plaintextlen, sizeof plaintext,
1364 ciphertext, ciphertextlen);
1365 if (rv != SECSuccess) {
1366 goto loser;
1367 }
1368
1369 fputs(buf, aesresp);
1370 fputs("PLAINTEXT = ", aesresp);
1371 to_hex_str(buf, plaintext, plaintextlen);
1372 fputs(buf, aesresp);
1373 fputc('\n', aesresp);
1374 continue;
1375 }
1376 }
1377loser:
1378 fclose(aesreq);
1379}
1380
1381/*
1382 * Generate Key[i+1] from Key[i], CT[j-1], and CT[j] for AES Monte Carlo
1383 * Test (MCT) in ECB and CBC modes.
1384 */
1385void
1386aes_mct_next_key(unsigned char *key, unsigned int keysize,
1387 const unsigned char *ciphertext_1, const unsigned char *ciphertext)
1388{
1389 int k;
1390
1391 switch (keysize) {
1392 case 16: /* 128-bit key */
1393 /* Key[i+1] = Key[i] xor CT[j] */
1394 for (k = 0; k < 16; k++) {
1395 key[k] ^= ciphertext[k];
1396 }
1397 break;
1398 case 24: /* 192-bit key */
1399 /*
1400 * Key[i+1] = Key[i] xor (last 64-bits of
1401 * CT[j-1] || CT[j])
1402 */
1403 for (k = 0; k < 8; k++) {
1404 key[k] ^= ciphertext_1[k + 8];
1405 }
1406 for (k = 8; k < 24; k++) {
1407 key[k] ^= ciphertext[k - 8];
1408 }
1409 break;
1410 case 32: /* 256-bit key */
1411 /* Key[i+1] = Key[i] xor (CT[j-1] || CT[j]) */
1412 for (k = 0; k < 16; k++) {
1413 key[k] ^= ciphertext_1[k];
1414 }
1415 for (k = 16; k < 32; k++) {
1416 key[k] ^= ciphertext[k - 16];
1417 }
1418 break;
1419 }
1420}
1421
1422/*
1423 * Perform the AES Monte Carlo Test (MCT) in ECB mode. MCT exercises
1424 * our AES code in streaming mode because the plaintext or ciphertext
1425 * is generated block by block as we go, so we can't collect all the
1426 * plaintext or ciphertext in one buffer and encrypt or decrypt it in
1427 * one shot.
1428 *
1429 * reqfn is the pathname of the input REQUEST file.
1430 *
1431 * The output RESPONSE file is written to stdout.
1432 */
1433void
1434aes_ecb_mct(char *reqfn)
1435{
1436 char buf[80]; /* holds one line from the input REQUEST file.
1437 * needs to be large enough to hold the longest
1438 * line "KEY = <64 hex digits>\n".
1439 */
1440 FILE *aesreq; /* input stream from the REQUEST file */
1441 FILE *aesresp; /* output stream to the RESPONSE file */
1442 int i, j;
1443 int encrypt = 0; /* 1 means encrypt, 0 means decrypt */
1444 unsigned char key[32]; /* 128, 192, or 256 bits */
1445 unsigned int keysize = 0;
1446 unsigned char plaintext[16]; /* PT[j] */
1447 unsigned char plaintext_1[16]; /* PT[j-1] */
1448 unsigned char ciphertext[16]; /* CT[j] */
1449 unsigned char ciphertext_1[16]; /* CT[j-1] */
1450 unsigned char doublecheck[16];
1451 unsigned int outputlen;
1452 AESContext *cx = NULL((void*)0); /* the operation being tested */
1453 AESContext *cx2 = NULL((void*)0); /* the inverse operation done in parallel
1454 * to doublecheck our result.
1455 */
1456 SECStatus rv;
1457
1458 aesreq = fopen(reqfn, "r");
1459 aesresp = stdoutstdout;
1460 while (fgets(buf, sizeof buf, aesreq) != NULL((void*)0)) {
1461 /* a comment or blank line */
1462 if (buf[0] == '#' || buf[0] == '\n') {
1463 fputs(buf, aesresp);
1464 continue;
1465 }
1466 /* [ENCRYPT] or [DECRYPT] */
1467 if (buf[0] == '[') {
1468 if (strncmp(&buf[1], "ENCRYPT", 7) == 0) {
1469 encrypt = 1;
1470 } else {
1471 encrypt = 0;
1472 }
1473 fputs(buf, aesresp);
1474 continue;
1475 }
1476 /* "COUNT = x" begins a new data set */
1477 if (strncmp(buf, "COUNT", 5) == 0) {
1478 /* zeroize the variables for the test with this data set */
1479 memset(key, 0, sizeof key);
1480 keysize = 0;
1481 memset(plaintext, 0, sizeof plaintext);
1482 memset(ciphertext, 0, sizeof ciphertext);
1483 continue;
1484 }
1485 /* KEY = ... */
1486 if (strncmp(buf, "KEY", 3) == 0) {
1487 /* Key[0] = Key */
1488 i = 3;
1489 while (isspace(buf[i])((*__ctype_b_loc ())[(int) ((buf[i]))] & (unsigned short int
) _ISspace)
|| buf[i] == '=') {
1490 i++;
1491 }
1492 for (j = 0; isxdigit(buf[i])((*__ctype_b_loc ())[(int) ((buf[i]))] & (unsigned short int
) _ISxdigit)
; i += 2, j++) {
1493 hex_to_byteval(&buf[i], &key[j]);
1494 }
1495 keysize = j;
1496 continue;
1497 }
1498 /* PLAINTEXT = ... */
1499 if (strncmp(buf, "PLAINTEXT", 9) == 0) {
1500 /* sanity check */
1501 if (!encrypt) {
1502 goto loser;
1503 }
1504 /* PT[0] = PT */
1505 i = 9;
1506 while (isspace(buf[i])((*__ctype_b_loc ())[(int) ((buf[i]))] & (unsigned short int
) _ISspace)
|| buf[i] == '=') {
1507 i++;
1508 }
1509 for (j = 0; j < sizeof plaintext; i += 2, j++) {
1510 hex_to_byteval(&buf[i], &plaintext[j]);
1511 }
1512
1513 for (i = 0; i < 100; i++) {
1514 snprintf(buf, sizeof(buf), "COUNT = %d\n", i);
1515 fputs(buf, aesresp);
1516 /* Output Key[i] */
1517 fputs("KEY = ", aesresp);
1518 to_hex_str(buf, key, keysize);
1519 fputs(buf, aesresp);
1520 fputc('\n', aesresp);
1521 /* Output PT[0] */
1522 fputs("PLAINTEXT = ", aesresp);
1523 to_hex_str(buf, plaintext, sizeof plaintext);
1524 fputs(buf, aesresp);
1525 fputc('\n', aesresp);
1526
1527 cx = AES_CreateContext(key, NULL((void*)0), NSS_AES0,
1528 PR_TRUE1, keysize, 16);
1529 if (cx == NULL((void*)0)) {
1530 goto loser;
1531 }
1532 /*
1533 * doublecheck our result by decrypting the result
1534 * and comparing the output with the plaintext.
1535 */
1536 cx2 = AES_CreateContext(key, NULL((void*)0), NSS_AES0,
1537 PR_FALSE0, keysize, 16);
1538 if (cx2 == NULL((void*)0)) {
1539 goto loser;
1540 }
1541 for (j = 0; j < 1000; j++) {
1542 /* Save CT[j-1] */
1543 memcpy(ciphertext_1, ciphertext, sizeof ciphertext);
1544
1545 /* CT[j] = AES(Key[i], PT[j]) */
1546 outputlen = 0;
1547 rv = AES_Encrypt(cx,
1548 ciphertext, &outputlen, sizeof ciphertext,
1549 plaintext, sizeof plaintext);
1550 if (rv != SECSuccess) {
1551 goto loser;
1552 }
1553 if (outputlen != sizeof plaintext) {
1554 goto loser;
1555 }
1556
1557 /* doublecheck our result */
1558 outputlen = 0;
1559 rv = AES_Decrypt(cx2,
1560 doublecheck, &outputlen, sizeof doublecheck,
1561 ciphertext, sizeof ciphertext);
1562 if (rv != SECSuccess) {
1563 goto loser;
1564 }
1565 if (outputlen != sizeof ciphertext) {
1566 goto loser;
1567 }
1568 if (memcmp(doublecheck, plaintext, sizeof plaintext)) {
1569 goto loser;
1570 }
1571
1572 /* PT[j+1] = CT[j] */
1573 memcpy(plaintext, ciphertext, sizeof plaintext);
1574 }
1575 AES_DestroyContext(cx, PR_TRUE1);
1576 cx = NULL((void*)0);
1577 AES_DestroyContext(cx2, PR_TRUE1);
1578 cx2 = NULL((void*)0);
1579
1580 /* Output CT[j] */
1581 fputs("CIPHERTEXT = ", aesresp);
1582 to_hex_str(buf, ciphertext, sizeof ciphertext);
1583 fputs(buf, aesresp);
1584 fputc('\n', aesresp);
1585
1586 /* Key[i+1] = Key[i] xor ... */
1587 aes_mct_next_key(key, keysize, ciphertext_1, ciphertext);
1588 /* PT[0] = CT[j] */
1589 /* done at the end of the for(j) loop */
1590
1591 fputc('\n', aesresp);
1592 }
1593
1594 continue;
1595 }
1596 /* CIPHERTEXT = ... */
1597 if (strncmp(buf, "CIPHERTEXT", 10) == 0) {
1598 /* sanity check */
1599 if (encrypt) {
1600 goto loser;
1601 }
1602 /* CT[0] = CT */
1603 i = 10;
1604 while (isspace(buf[i])((*__ctype_b_loc ())[(int) ((buf[i]))] & (unsigned short int
) _ISspace)
|| buf[i] == '=') {
1605 i++;
1606 }
1607 for (j = 0; isxdigit(buf[i])((*__ctype_b_loc ())[(int) ((buf[i]))] & (unsigned short int
) _ISxdigit)
; i += 2, j++) {
1608 hex_to_byteval(&buf[i], &ciphertext[j]);
1609 }
1610
1611 for (i = 0; i < 100; i++) {
1612 snprintf(buf, sizeof(buf), "COUNT = %d\n", i);
1613 fputs(buf, aesresp);
1614 /* Output Key[i] */
1615 fputs("KEY = ", aesresp);
1616 to_hex_str(buf, key, keysize);
1617 fputs(buf, aesresp);
1618 fputc('\n', aesresp);
1619 /* Output CT[0] */
1620 fputs("CIPHERTEXT = ", aesresp);
1621 to_hex_str(buf, ciphertext, sizeof ciphertext);
1622 fputs(buf, aesresp);
1623 fputc('\n', aesresp);
1624
1625 cx = AES_CreateContext(key, NULL((void*)0), NSS_AES0,
1626 PR_FALSE0, keysize, 16);
1627 if (cx == NULL((void*)0)) {
1628 goto loser;
1629 }
1630 /*
1631 * doublecheck our result by encrypting the result
1632 * and comparing the output with the ciphertext.
1633 */
1634 cx2 = AES_CreateContext(key, NULL((void*)0), NSS_AES0,
1635 PR_TRUE1, keysize, 16);
1636 if (cx2 == NULL((void*)0)) {
1637 goto loser;
1638 }
1639 for (j = 0; j < 1000; j++) {
1640 /* Save PT[j-1] */
1641 memcpy(plaintext_1, plaintext, sizeof plaintext);
1642
1643 /* PT[j] = AES(Key[i], CT[j]) */
1644 outputlen = 0;
1645 rv = AES_Decrypt(cx,
1646 plaintext, &outputlen, sizeof plaintext,
1647 ciphertext, sizeof ciphertext);
1648 if (rv != SECSuccess) {
1649 goto loser;
1650 }
1651 if (outputlen != sizeof ciphertext) {
1652 goto loser;
1653 }
1654
1655 /* doublecheck our result */
1656 outputlen = 0;
1657 rv = AES_Encrypt(cx2,
1658 doublecheck, &outputlen, sizeof doublecheck,
1659 plaintext, sizeof plaintext);
1660 if (rv != SECSuccess) {
1661 goto loser;
1662 }
1663 if (outputlen != sizeof plaintext) {
1664 goto loser;
1665 }
1666 if (memcmp(doublecheck, ciphertext, sizeof ciphertext)) {
1667 goto loser;
1668 }
1669
1670 /* CT[j+1] = PT[j] */
1671 memcpy(ciphertext, plaintext, sizeof ciphertext);
1672 }
1673 AES_DestroyContext(cx, PR_TRUE1);
1674 cx = NULL((void*)0);
1675 AES_DestroyContext(cx2, PR_TRUE1);
1676 cx2 = NULL((void*)0);
1677
1678 /* Output PT[j] */
1679 fputs("PLAINTEXT = ", aesresp);
1680 to_hex_str(buf, plaintext, sizeof plaintext);
1681 fputs(buf, aesresp);
1682 fputc('\n', aesresp);
1683
1684 /* Key[i+1] = Key[i] xor ... */
1685 aes_mct_next_key(key, keysize, plaintext_1, plaintext);
1686 /* CT[0] = PT[j] */
1687 /* done at the end of the for(j) loop */
1688
1689 fputc('\n', aesresp);
1690 }
1691
1692 continue;
1693 }
1694 }
1695loser:
1696 if (cx != NULL((void*)0)) {
1697 AES_DestroyContext(cx, PR_TRUE1);
1698 }
1699 if (cx2 != NULL((void*)0)) {
1700 AES_DestroyContext(cx2, PR_TRUE1);
1701 }
1702 fclose(aesreq);
1703}
1704
1705/*
1706 * Perform the AES Monte Carlo Test (MCT) in CBC mode. MCT exercises
1707 * our AES code in streaming mode because the plaintext or ciphertext
1708 * is generated block by block as we go, so we can't collect all the
1709 * plaintext or ciphertext in one buffer and encrypt or decrypt it in
1710 * one shot.
1711 *
1712 * reqfn is the pathname of the input REQUEST file.
1713 *
1714 * The output RESPONSE file is written to stdout.
1715 */
1716void
1717aes_cbc_mct(char *reqfn)
1718{
1719 char buf[80]; /* holds one line from the input REQUEST file.
1720 * needs to be large enough to hold the longest
1721 * line "KEY = <64 hex digits>\n".
1722 */
1723 FILE *aesreq; /* input stream from the REQUEST file */
1724 FILE *aesresp; /* output stream to the RESPONSE file */
1725 int i, j;
1726 int encrypt = 0; /* 1 means encrypt, 0 means decrypt */
1727 unsigned char key[32]; /* 128, 192, or 256 bits */
1728 unsigned int keysize = 0;
1729 unsigned char iv[16];
1730 unsigned char plaintext[16]; /* PT[j] */
1731 unsigned char plaintext_1[16]; /* PT[j-1] */
1732 unsigned char ciphertext[16]; /* CT[j] */
1733 unsigned char ciphertext_1[16]; /* CT[j-1] */
1734 unsigned char doublecheck[16];
1735 unsigned int outputlen;
1736 AESContext *cx = NULL((void*)0); /* the operation being tested */
1737 AESContext *cx2 = NULL((void*)0); /* the inverse operation done in parallel
1738 * to doublecheck our result.
1739 */
1740 SECStatus rv;
1741
1742 aesreq = fopen(reqfn, "r");
1743 aesresp = stdoutstdout;
1744 while (fgets(buf, sizeof buf, aesreq) != NULL((void*)0)) {
1745 /* a comment or blank line */
1746 if (buf[0] == '#' || buf[0] == '\n') {
1747 fputs(buf, aesresp);
1748 continue;
1749 }
1750 /* [ENCRYPT] or [DECRYPT] */
1751 if (buf[0] == '[') {
1752 if (strncmp(&buf[1], "ENCRYPT", 7) == 0) {
1753 encrypt = 1;
1754 } else {
1755 encrypt = 0;
1756 }
1757 fputs(buf, aesresp);
1758 continue;
1759 }
1760 /* "COUNT = x" begins a new data set */
1761 if (strncmp(buf, "COUNT", 5) == 0) {
1762 /* zeroize the variables for the test with this data set */
1763 memset(key, 0, sizeof key);
1764 keysize = 0;
1765 memset(iv, 0, sizeof iv);
1766 memset(plaintext, 0, sizeof plaintext);
1767 memset(ciphertext, 0, sizeof ciphertext);
1768 continue;
1769 }
1770 /* KEY = ... */
1771 if (strncmp(buf, "KEY", 3) == 0) {
1772 /* Key[0] = Key */
1773 i = 3;
1774 while (isspace(buf[i])((*__ctype_b_loc ())[(int) ((buf[i]))] & (unsigned short int
) _ISspace)
|| buf[i] == '=') {
1775 i++;
1776 }
1777 for (j = 0; isxdigit(buf[i])((*__ctype_b_loc ())[(int) ((buf[i]))] & (unsigned short int
) _ISxdigit)
; i += 2, j++) {
1778 hex_to_byteval(&buf[i], &key[j]);
1779 }
1780 keysize = j;
1781 continue;
1782 }
1783 /* IV = ... */
1784 if (strncmp(buf, "IV", 2) == 0) {
1785 /* IV[0] = IV */
1786 i = 2;
1787 while (isspace(buf[i])((*__ctype_b_loc ())[(int) ((buf[i]))] & (unsigned short int
) _ISspace)
|| buf[i] == '=') {
1788 i++;
1789 }
1790 for (j = 0; j < sizeof iv; i += 2, j++) {
1791 hex_to_byteval(&buf[i], &iv[j]);
1792 }
1793 continue;
1794 }
1795 /* PLAINTEXT = ... */
1796 if (strncmp(buf, "PLAINTEXT", 9) == 0) {
1797 /* sanity check */
1798 if (!encrypt) {
1799 goto loser;
1800 }
1801 /* PT[0] = PT */
1802 i = 9;
1803 while (isspace(buf[i])((*__ctype_b_loc ())[(int) ((buf[i]))] & (unsigned short int
) _ISspace)
|| buf[i] == '=') {
1804 i++;
1805 }
1806 for (j = 0; j < sizeof plaintext; i += 2, j++) {
1807 hex_to_byteval(&buf[i], &plaintext[j]);
1808 }
1809
1810 for (i = 0; i < 100; i++) {
1811 snprintf(buf, sizeof(buf), "COUNT = %d\n", i);
1812 fputs(buf, aesresp);
1813 /* Output Key[i] */
1814 fputs("KEY = ", aesresp);
1815 to_hex_str(buf, key, keysize);
1816 fputs(buf, aesresp);
1817 fputc('\n', aesresp);
1818 /* Output IV[i] */
1819 fputs("IV = ", aesresp);
1820 to_hex_str(buf, iv, sizeof iv);
1821 fputs(buf, aesresp);
1822 fputc('\n', aesresp);
1823 /* Output PT[0] */
1824 fputs("PLAINTEXT = ", aesresp);
1825 to_hex_str(buf, plaintext, sizeof plaintext);
1826 fputs(buf, aesresp);
1827 fputc('\n', aesresp);
1828
1829 cx = AES_CreateContext(key, iv, NSS_AES_CBC1,
1830 PR_TRUE1, keysize, 16);
1831 if (cx == NULL((void*)0)) {
1832 goto loser;
1833 }
1834 /*
1835 * doublecheck our result by decrypting the result
1836 * and comparing the output with the plaintext.
1837 */
1838 cx2 = AES_CreateContext(key, iv, NSS_AES_CBC1,
1839 PR_FALSE0, keysize, 16);
1840 if (cx2 == NULL((void*)0)) {
1841 goto loser;
1842 }
1843 /* CT[-1] = IV[i] */
1844 memcpy(ciphertext, iv, sizeof ciphertext);
1845 for (j = 0; j < 1000; j++) {
1846 /* Save CT[j-1] */
1847 memcpy(ciphertext_1, ciphertext, sizeof ciphertext);
1848 /*
1849 * If ( j=0 )
1850 * CT[j] = AES(Key[i], IV[i], PT[j])
1851 * PT[j+1] = IV[i] (= CT[j-1])
1852 * Else
1853 * CT[j] = AES(Key[i], PT[j])
1854 * PT[j+1] = CT[j-1]
1855 */
1856 outputlen = 0;
1857 rv = AES_Encrypt(cx,
1858 ciphertext, &outputlen, sizeof ciphertext,
1859 plaintext, sizeof plaintext);
1860 if (rv != SECSuccess) {
1861 goto loser;
1862 }
1863 if (outputlen != sizeof plaintext) {
1864 goto loser;
1865 }
1866
1867 /* doublecheck our result */
1868 outputlen = 0;
1869 rv = AES_Decrypt(cx2,
1870 doublecheck, &outputlen, sizeof doublecheck,
1871 ciphertext, sizeof ciphertext);
1872 if (rv != SECSuccess) {
1873 goto loser;
1874 }
1875 if (outputlen != sizeof ciphertext) {
1876 goto loser;
1877 }
1878 if (memcmp(doublecheck, plaintext, sizeof plaintext)) {
1879 goto loser;
1880 }
1881
1882 memcpy(plaintext, ciphertext_1, sizeof plaintext);
1883 }
1884 AES_DestroyContext(cx, PR_TRUE1);
1885 cx = NULL((void*)0);
1886 AES_DestroyContext(cx2, PR_TRUE1);
1887 cx2 = NULL((void*)0);
1888
1889 /* Output CT[j] */
1890 fputs("CIPHERTEXT = ", aesresp);
1891 to_hex_str(buf, ciphertext, sizeof ciphertext);
1892 fputs(buf, aesresp);
1893 fputc('\n', aesresp);
1894
1895 /* Key[i+1] = Key[i] xor ... */
1896 aes_mct_next_key(key, keysize, ciphertext_1, ciphertext);
1897 /* IV[i+1] = CT[j] */
1898 memcpy(iv, ciphertext, sizeof iv);
1899 /* PT[0] = CT[j-1] */
1900 /* done at the end of the for(j) loop */
1901
1902 fputc('\n', aesresp);
1903 }
1904
1905 continue;
1906 }
1907 /* CIPHERTEXT = ... */
1908 if (strncmp(buf, "CIPHERTEXT", 10) == 0) {
1909 /* sanity check */
1910 if (encrypt) {
1911 goto loser;
1912 }
1913 /* CT[0] = CT */
1914 i = 10;
1915 while (isspace(buf[i])((*__ctype_b_loc ())[(int) ((buf[i]))] & (unsigned short int
) _ISspace)
|| buf[i] == '=') {
1916 i++;
1917 }
1918 for (j = 0; isxdigit(buf[i])((*__ctype_b_loc ())[(int) ((buf[i]))] & (unsigned short int
) _ISxdigit)
; i += 2, j++) {
1919 hex_to_byteval(&buf[i], &ciphertext[j]);
1920 }
1921
1922 for (i = 0; i < 100; i++) {
1923 snprintf(buf, sizeof(buf), "COUNT = %d\n", i);
1924 fputs(buf, aesresp);
1925 /* Output Key[i] */
1926 fputs("KEY = ", aesresp);
1927 to_hex_str(buf, key, keysize);
1928 fputs(buf, aesresp);
1929 fputc('\n', aesresp);
1930 /* Output IV[i] */
1931 fputs("IV = ", aesresp);
1932 to_hex_str(buf, iv, sizeof iv);
1933 fputs(buf, aesresp);
1934 fputc('\n', aesresp);
1935 /* Output CT[0] */
1936 fputs("CIPHERTEXT = ", aesresp);
1937 to_hex_str(buf, ciphertext, sizeof ciphertext);
1938 fputs(buf, aesresp);
1939 fputc('\n', aesresp);
1940
1941 cx = AES_CreateContext(key, iv, NSS_AES_CBC1,
1942 PR_FALSE0, keysize, 16);
1943 if (cx == NULL((void*)0)) {
1944 goto loser;
1945 }
1946 /*
1947 * doublecheck our result by encrypting the result
1948 * and comparing the output with the ciphertext.
1949 */
1950 cx2 = AES_CreateContext(key, iv, NSS_AES_CBC1,
1951 PR_TRUE1, keysize, 16);
1952 if (cx2 == NULL((void*)0)) {
1953 goto loser;
1954 }
1955 /* PT[-1] = IV[i] */
1956 memcpy(plaintext, iv, sizeof plaintext);
1957 for (j = 0; j < 1000; j++) {
1958 /* Save PT[j-1] */
1959 memcpy(plaintext_1, plaintext, sizeof plaintext);
1960 /*
1961 * If ( j=0 )
1962 * PT[j] = AES(Key[i], IV[i], CT[j])
1963 * CT[j+1] = IV[i] (= PT[j-1])
1964 * Else
1965 * PT[j] = AES(Key[i], CT[j])
1966 * CT[j+1] = PT[j-1]
1967 */
1968 outputlen = 0;
1969 rv = AES_Decrypt(cx,
1970 plaintext, &outputlen, sizeof plaintext,
1971 ciphertext, sizeof ciphertext);
1972 if (rv != SECSuccess) {
1973 goto loser;
1974 }
1975 if (outputlen != sizeof ciphertext) {
1976 goto loser;
1977 }
1978
1979 /* doublecheck our result */
1980 outputlen = 0;
1981 rv = AES_Encrypt(cx2,
1982 doublecheck, &outputlen, sizeof doublecheck,
1983 plaintext, sizeof plaintext);
1984 if (rv != SECSuccess) {
1985 goto loser;
1986 }
1987 if (outputlen != sizeof plaintext) {
1988 goto loser;
1989 }
1990 if (memcmp(doublecheck, ciphertext, sizeof ciphertext)) {
1991 goto loser;
1992 }
1993
1994 memcpy(ciphertext, plaintext_1, sizeof ciphertext);
1995 }
1996 AES_DestroyContext(cx, PR_TRUE1);
1997 cx = NULL((void*)0);
1998 AES_DestroyContext(cx2, PR_TRUE1);
1999 cx2 = NULL((void*)0);
2000
2001 /* Output PT[j] */
2002 fputs("PLAINTEXT = ", aesresp);
2003 to_hex_str(buf, plaintext, sizeof plaintext);
2004 fputs(buf, aesresp);
2005 fputc('\n', aesresp);
2006
2007 /* Key[i+1] = Key[i] xor ... */
2008 aes_mct_next_key(key, keysize, plaintext_1, plaintext);
2009 /* IV[i+1] = PT[j] */
2010 memcpy(iv, plaintext, sizeof iv);
2011 /* CT[0] = PT[j-1] */
2012 /* done at the end of the for(j) loop */
2013
2014 fputc('\n', aesresp);
2015 }
2016
2017 continue;
2018 }
2019 }
2020loser:
2021 if (cx != NULL((void*)0)) {
2022 AES_DestroyContext(cx, PR_TRUE1);
2023 }
2024 if (cx2 != NULL((void*)0)) {
2025 AES_DestroyContext(cx2, PR_TRUE1);
2026 }
2027 fclose(aesreq);
2028}
2029
2030void
2031write_compact_string(FILE *out, unsigned char *hash, unsigned int len)
2032{
2033 unsigned int i;
2034 int j, count = 0, last = -1, z = 0;
2035 long start = ftell(out);
2036 for (i = 0; i < len; i++) {
2037 for (j = 7; j >= 0; j--) {
2038 if (last < 0) {
2039 last = (hash[i] & (1 << j)) ? 1 : 0;
2040 fprintf(out, "%d ", last);
2041 count = 1;
2042 } else if (hash[i] & (1 << j)) {
2043 if (last) {
2044 count++;
2045 } else {
2046 last = 0;
2047 fprintf(out, "%d ", count);
2048 count = 1;
2049 z++;
2050 }
2051 } else {
2052 if (!last) {
2053 count++;
2054 } else {
2055 last = 1;
2056 fprintf(out, "%d ", count);
2057 count = 1;
2058 z++;
2059 }
2060 }
2061 }
2062 }
2063 fprintf(out, "^\n");
2064 fseek(out, start, SEEK_SET0);
2065 fprintf(out, "%d ", z);
2066 fseek(out, 0, SEEK_END2);
2067}
2068
2069int
2070get_next_line(FILE *req, char *key, char *val, FILE *rsp)
2071{
2072 int ignore = 0;
2073 char *writeto = key;
2074 int w = 0;
2075 int c;
2076 while ((c = fgetc(req)) != EOF(-1)) {
2077 if (ignore) {
2078 fprintf(rsp, "%c", c);
2079 if (c == '\n')
2080 return ignore;
2081 } else if (c == '\n') {
2082 break;
2083 } else if (c == '#') {
2084 ignore = 1;
2085 fprintf(rsp, "%c", c);
2086 } else if (c == '=') {
2087 writeto[w] = '\0';
2088 w = 0;
2089 writeto = val;
2090 } else if (c == ' ' || c == '[' || c == ']') {
2091 continue;
2092 } else {
2093 writeto[w++] = c;
2094 }
2095 }
2096 writeto[w] = '\0';
2097 return (c == EOF(-1)) ? -1 : ignore;
2098}
2099
2100typedef struct curveNameTagPairStr {
2101 char *curveName;
2102 SECOidTag curveOidTag;
2103} CurveNameTagPair;
2104
2105#define DEFAULT_CURVE_OID_TAGSEC_OID_ANSIX962_EC_PRIME192V1 SEC_OID_SECG_EC_SECP192R1SEC_OID_ANSIX962_EC_PRIME192V1
2106/* #define DEFAULT_CURVE_OID_TAG SEC_OID_SECG_EC_SECP160R1 */
2107
2108static CurveNameTagPair nameTagPair[] = {
2109 { "sect163k1", SEC_OID_SECG_EC_SECT163K1 },
2110 { "nistk163", SEC_OID_SECG_EC_SECT163K1 },
2111 { "sect163r1", SEC_OID_SECG_EC_SECT163R1 },
2112 { "sect163r2", SEC_OID_SECG_EC_SECT163R2 },
2113 { "nistb163", SEC_OID_SECG_EC_SECT163R2 },
2114 { "sect193r1", SEC_OID_SECG_EC_SECT193R1 },
2115 { "sect193r2", SEC_OID_SECG_EC_SECT193R2 },
2116 { "sect233k1", SEC_OID_SECG_EC_SECT233K1 },
2117 { "nistk233", SEC_OID_SECG_EC_SECT233K1 },
2118 { "sect233r1", SEC_OID_SECG_EC_SECT233R1 },
2119 { "nistb233", SEC_OID_SECG_EC_SECT233R1 },
2120 { "sect239k1", SEC_OID_SECG_EC_SECT239K1 },
2121 { "sect283k1", SEC_OID_SECG_EC_SECT283K1 },
2122 { "nistk283", SEC_OID_SECG_EC_SECT283K1 },
2123 { "sect283r1", SEC_OID_SECG_EC_SECT283R1 },
2124 { "nistb283", SEC_OID_SECG_EC_SECT283R1 },
2125 { "sect409k1", SEC_OID_SECG_EC_SECT409K1 },
2126 { "nistk409", SEC_OID_SECG_EC_SECT409K1 },
2127 { "sect409r1", SEC_OID_SECG_EC_SECT409R1 },
2128 { "nistb409", SEC_OID_SECG_EC_SECT409R1 },
2129 { "sect571k1", SEC_OID_SECG_EC_SECT571K1 },
2130 { "nistk571", SEC_OID_SECG_EC_SECT571K1 },
2131 { "sect571r1", SEC_OID_SECG_EC_SECT571R1 },
2132 { "nistb571", SEC_OID_SECG_EC_SECT571R1 },
2133 { "secp160k1", SEC_OID_SECG_EC_SECP160K1 },
2134 { "secp160r1", SEC_OID_SECG_EC_SECP160R1 },
2135 { "secp160r2", SEC_OID_SECG_EC_SECP160R2 },
2136 { "secp192k1", SEC_OID_SECG_EC_SECP192K1 },
2137 { "secp192r1", SEC_OID_SECG_EC_SECP192R1SEC_OID_ANSIX962_EC_PRIME192V1 },
2138 { "nistp192", SEC_OID_SECG_EC_SECP192R1SEC_OID_ANSIX962_EC_PRIME192V1 },
2139 { "secp224k1", SEC_OID_SECG_EC_SECP224K1 },
2140 { "secp224r1", SEC_OID_SECG_EC_SECP224R1 },
2141 { "nistp224", SEC_OID_SECG_EC_SECP224R1 },
2142 { "secp256k1", SEC_OID_SECG_EC_SECP256K1 },
2143 { "secp256r1", SEC_OID_SECG_EC_SECP256R1SEC_OID_ANSIX962_EC_PRIME256V1 },
2144 { "nistp256", SEC_OID_SECG_EC_SECP256R1SEC_OID_ANSIX962_EC_PRIME256V1 },
2145 { "secp384r1", SEC_OID_SECG_EC_SECP384R1 },
2146 { "nistp384", SEC_OID_SECG_EC_SECP384R1 },
2147 { "secp521r1", SEC_OID_SECG_EC_SECP521R1 },
2148 { "nistp521", SEC_OID_SECG_EC_SECP521R1 },
2149
2150 { "prime192v1", SEC_OID_ANSIX962_EC_PRIME192V1 },
2151 { "prime192v2", SEC_OID_ANSIX962_EC_PRIME192V2 },
2152 { "prime192v3", SEC_OID_ANSIX962_EC_PRIME192V3 },
2153 { "prime239v1", SEC_OID_ANSIX962_EC_PRIME239V1 },
2154 { "prime239v2", SEC_OID_ANSIX962_EC_PRIME239V2 },
2155 { "prime239v3", SEC_OID_ANSIX962_EC_PRIME239V3 },
2156
2157 { "c2pnb163v1", SEC_OID_ANSIX962_EC_C2PNB163V1 },
2158 { "c2pnb163v2", SEC_OID_ANSIX962_EC_C2PNB163V2 },
2159 { "c2pnb163v3", SEC_OID_ANSIX962_EC_C2PNB163V3 },
2160 { "c2pnb176v1", SEC_OID_ANSIX962_EC_C2PNB176V1 },
2161 { "c2tnb191v1", SEC_OID_ANSIX962_EC_C2TNB191V1 },
2162 { "c2tnb191v2", SEC_OID_ANSIX962_EC_C2TNB191V2 },
2163 { "c2tnb191v3", SEC_OID_ANSIX962_EC_C2TNB191V3 },
2164 { "c2onb191v4", SEC_OID_ANSIX962_EC_C2ONB191V4 },
2165 { "c2onb191v5", SEC_OID_ANSIX962_EC_C2ONB191V5 },
2166 { "c2pnb208w1", SEC_OID_ANSIX962_EC_C2PNB208W1 },
2167 { "c2tnb239v1", SEC_OID_ANSIX962_EC_C2TNB239V1 },
2168 { "c2tnb239v2", SEC_OID_ANSIX962_EC_C2TNB239V2 },
2169 { "c2tnb239v3", SEC_OID_ANSIX962_EC_C2TNB239V3 },
2170 { "c2onb239v4", SEC_OID_ANSIX962_EC_C2ONB239V4 },
2171 { "c2onb239v5", SEC_OID_ANSIX962_EC_C2ONB239V5 },
2172 { "c2pnb272w1", SEC_OID_ANSIX962_EC_C2PNB272W1 },
2173 { "c2pnb304w1", SEC_OID_ANSIX962_EC_C2PNB304W1 },
2174 { "c2tnb359v1", SEC_OID_ANSIX962_EC_C2TNB359V1 },
2175 { "c2pnb368w1", SEC_OID_ANSIX962_EC_C2PNB368W1 },
2176 { "c2tnb431r1", SEC_OID_ANSIX962_EC_C2TNB431R1 },
2177
2178 { "secp112r1", SEC_OID_SECG_EC_SECP112R1 },
2179 { "secp112r2", SEC_OID_SECG_EC_SECP112R2 },
2180 { "secp128r1", SEC_OID_SECG_EC_SECP128R1 },
2181 { "secp128r2", SEC_OID_SECG_EC_SECP128R2 },
2182
2183 { "sect113r1", SEC_OID_SECG_EC_SECT113R1 },
2184 { "sect113r2", SEC_OID_SECG_EC_SECT113R2 },
2185 { "sect131r1", SEC_OID_SECG_EC_SECT131R1 },
2186 { "sect131r2", SEC_OID_SECG_EC_SECT131R2 },
2187};
2188
2189static SECItem *
2190getECParams(const char *curve)
2191{
2192 SECItem *ecparams;
2193 SECOidData *oidData = NULL((void*)0);
2194 SECOidTag curveOidTag = SEC_OID_UNKNOWN; /* default */
2195 int i, numCurves;
2196
2197 if (curve != NULL((void*)0)) {
2198 numCurves = sizeof(nameTagPair) / sizeof(CurveNameTagPair);
2199 for (i = 0; ((i < numCurves) && (curveOidTag == SEC_OID_UNKNOWN));
2200 i++) {
2201 if (PL_strcmp(curve, nameTagPair[i].curveName) == 0)
2202 curveOidTag = nameTagPair[i].curveOidTag;
2203 }
2204 }
2205
2206 /* Return NULL if curve name is not recognized */
2207 if ((curveOidTag == SEC_OID_UNKNOWN) ||
2208 (oidData = SECOID_FindOIDByTagSECOID_FindOIDByTag_Util(curveOidTag)) == NULL((void*)0)) {
2209 fprintf(stderrstderr, "Unrecognized elliptic curve %s\n", curve);
2210 return NULL((void*)0);
2211 }
2212
2213 ecparams = SECITEM_AllocItemSECITEM_AllocItem_Util(NULL((void*)0), NULL((void*)0), (2 + oidData->oid.len));
2214
2215 /*
2216 * ecparams->data needs to contain the ASN encoding of an object ID (OID)
2217 * representing the named curve. The actual OID is in
2218 * oidData->oid.data so we simply prepend 0x06 and OID length
2219 */
2220 ecparams->data[0] = SEC_ASN1_OBJECT_ID0x06;
2221 ecparams->data[1] = oidData->oid.len;
2222 memcpy(ecparams->data + 2, oidData->oid.data, oidData->oid.len);
2223
2224 return ecparams;
2225}
2226
2227/*
2228 * HASH_ functions are available to full NSS apps and internally inside
2229 * freebl, but not exported to users of freebl. Create short stubs to
2230 * replace the functionality for fipstest.
2231 */
2232SECStatus
2233fips_hashBuf(HASH_HashType type, unsigned char *hashBuf,
2234 unsigned char *msg, int len)
2235{
2236 SECStatus rv = SECFailure;
2237
2238 switch (type) {
2239 case HASH_AlgSHA1:
2240 rv = SHA1_HashBuf(hashBuf, msg, len);
2241 break;
2242 case HASH_AlgSHA224:
2243 rv = SHA224_HashBuf(hashBuf, msg, len);
2244 break;
2245 case HASH_AlgSHA256:
2246 rv = SHA256_HashBuf(hashBuf, msg, len);
2247 break;
2248 case HASH_AlgSHA384:
2249 rv = SHA384_HashBuf(hashBuf, msg, len);
2250 break;
2251 case HASH_AlgSHA512:
2252 rv = SHA512_HashBuf(hashBuf, msg, len);
2253 break;
2254 default:
2255 break;
2256 }
2257 return rv;
2258}
2259
2260int
2261fips_hashLen(HASH_HashType type)
2262{
2263 int len = 0;
2264
2265 switch (type) {
2266 case HASH_AlgSHA1:
2267 len = SHA1_LENGTH20;
2268 break;
2269 case HASH_AlgSHA224:
2270 len = SHA224_LENGTH28;
2271 break;
2272 case HASH_AlgSHA256:
2273 len = SHA256_LENGTH32;
2274 break;
2275 case HASH_AlgSHA384:
2276 len = SHA384_LENGTH48;
2277 break;
2278 case HASH_AlgSHA512:
2279 len = SHA512_LENGTH64;
2280 break;
2281 default:
2282 break;
2283 }
2284 return len;
2285}
2286
2287SECOidTag
2288fips_hashOid(HASH_HashType type)
2289{
2290 SECOidTag oid = SEC_OID_UNKNOWN;
2291
2292 switch (type) {
2293 case HASH_AlgSHA1:
2294 oid = SEC_OID_SHA1;
2295 break;
2296 case HASH_AlgSHA224:
2297 oid = SEC_OID_SHA224;
2298 break;
2299 case HASH_AlgSHA256:
2300 oid = SEC_OID_SHA256;
2301 break;
2302 case HASH_AlgSHA384:
2303 oid = SEC_OID_SHA384;
2304 break;
2305 case HASH_AlgSHA512:
2306 oid = SEC_OID_SHA512;
2307 break;
2308 default:
2309 break;
2310 }
2311 return oid;
2312}
2313
2314HASH_HashType
2315sha_get_hashType(int hashbits)
2316{
2317 HASH_HashType hashType = HASH_AlgNULL;
2318
2319 switch (hashbits) {
2320 case 1:
2321 case (SHA1_LENGTH20 * PR_BITS_PER_BYTE8):
2322 hashType = HASH_AlgSHA1;
2323 break;
2324 case (SHA224_LENGTH28 * PR_BITS_PER_BYTE8):
2325 hashType = HASH_AlgSHA224;
2326 break;
2327 case (SHA256_LENGTH32 * PR_BITS_PER_BYTE8):
2328 hashType = HASH_AlgSHA256;
2329 break;
2330 case (SHA384_LENGTH48 * PR_BITS_PER_BYTE8):
2331 hashType = HASH_AlgSHA384;
2332 break;
2333 case (SHA512_LENGTH64 * PR_BITS_PER_BYTE8):
2334 hashType = HASH_AlgSHA512;
2335 break;
2336 default:
2337 break;
2338 }
2339 return hashType;
2340}
2341
2342HASH_HashType
2343hash_string_to_hashType(const char *src)
2344{
2345 HASH_HashType shaAlg = HASH_AlgNULL;
2346 if (strncmp(src, "SHA-1", 5) == 0) {
2347 shaAlg = HASH_AlgSHA1;
2348 } else if (strncmp(src, "SHA-224", 7) == 0) {
2349 shaAlg = HASH_AlgSHA224;
2350 } else if (strncmp(src, "SHA-256", 7) == 0) {
2351 shaAlg = HASH_AlgSHA256;
2352 } else if (strncmp(src, "SHA-384", 7) == 0) {
2353 shaAlg = HASH_AlgSHA384;
2354 } else if (strncmp(src, "SHA-512", 7) == 0) {
2355 shaAlg = HASH_AlgSHA512;
2356 } else if (strncmp(src, "SHA1", 4) == 0) {
2357 shaAlg = HASH_AlgSHA1;
2358 } else if (strncmp(src, "SHA224", 6) == 0) {
2359 shaAlg = HASH_AlgSHA224;
2360 } else if (strncmp(src, "SHA256", 6) == 0) {
2361 shaAlg = HASH_AlgSHA256;
2362 } else if (strncmp(src, "SHA384", 6) == 0) {
2363 shaAlg = HASH_AlgSHA384;
2364 } else if (strncmp(src, "SHA512", 6) == 0) {
2365 shaAlg = HASH_AlgSHA512;
2366 }
2367 return shaAlg;
2368}
2369
2370/*
2371 * Perform the ECDSA Key Pair Generation Test.
2372 *
2373 * reqfn is the pathname of the REQUEST file.
2374 *
2375 * The output RESPONSE file is written to stdout.
2376 */
2377void
2378ecdsa_keypair_test(char *reqfn)
2379{
2380 char buf[256]; /* holds one line from the input REQUEST file
2381 * or to the output RESPONSE file.
2382 * needs to be large enough to hold the longest
2383 * line "Qx = <144 hex digits>\n".
2384 */
2385 FILE *ecdsareq; /* input stream from the REQUEST file */
2386 FILE *ecdsaresp; /* output stream to the RESPONSE file */
2387 char curve[16]; /* "nistxddd" */
2388 ECParams *ecparams = NULL((void*)0);
2389 int N;
2390 int i;
2391 unsigned int len;
2392
2393 ecdsareq = fopen(reqfn, "r");
2394 ecdsaresp = stdoutstdout;
2395 strcpy(curve, "nist");
2396 while (fgets(buf, sizeof buf, ecdsareq) != NULL((void*)0)) {
2397 /* a comment or blank line */
2398 if (buf[0] == '#' || buf[0] == '\n') {
2399 fputs(buf, ecdsaresp);
2400 continue;
2401 }
2402 /* [X-ddd] */
2403 if (buf[0] == '[') {
2404 const char *src;
2405 char *dst;
2406 SECItem *encodedparams;
2407
2408 if (buf[1] == 'B') {
2409 fputs(buf, ecdsaresp);
2410 continue;
2411 }
2412 if (ecparams) {
2413 PORT_FreeArenaPORT_FreeArena_Util(ecparams->arena, PR_FALSE0);
2414 ecparams = NULL((void*)0);
2415 }
2416
2417 src = &buf[1];
2418 dst = &curve[4];
2419 *dst++ = tolower(*src);
2420 src += 2; /* skip the hyphen */
2421 *dst++ = *src++;
2422 *dst++ = *src++;
2423 *dst++ = *src++;
2424 *dst = '\0';
2425 encodedparams = getECParams(curve);
2426 if (encodedparams == NULL((void*)0)) {
2427 fprintf(stderrstderr, "Unknown curve %s.", curve);
2428 goto loser;
2429 }
2430 if (EC_DecodeParams(encodedparams, &ecparams) != SECSuccess) {
2431 fprintf(stderrstderr, "Curve %s not supported.\n", curve);
2432 goto loser;
2433 }
2434 SECITEM_FreeItemSECITEM_FreeItem_Util(encodedparams, PR_TRUE1);
2435 fputs(buf, ecdsaresp);
2436 continue;
2437 }
2438 /* N = x */
2439 if (buf[0] == 'N') {
2440 if (sscanf(buf, "N = %d", &N) != 1) {
2441 goto loser;
2442 }
2443 for (i = 0; i < N; i++) {
2444 ECPrivateKey *ecpriv;
2445
2446 if (EC_NewKey(ecparams, &ecpriv) != SECSuccess) {
2447 goto loser;
2448 }
2449 fputs("d = ", ecdsaresp);
2450 to_hex_str(buf, ecpriv->privateValue.data,
2451 ecpriv->privateValue.len);
2452 fputs(buf, ecdsaresp);
2453 fputc('\n', ecdsaresp);
2454 if (EC_ValidatePublicKey(ecparams, &ecpriv->publicValue) !=
2455 SECSuccess) {
2456 goto loser;
2457 }
2458 len = ecpriv->publicValue.len;
2459 if (len % 2 == 0) {
2460 goto loser;
2461 }
2462 len = (len - 1) / 2;
2463 if (ecpriv->publicValue.data[0] !=
2464 EC_POINT_FORM_UNCOMPRESSED0x04) {
2465 goto loser;
2466 }
2467 fputs("Qx = ", ecdsaresp);
2468 to_hex_str(buf, &ecpriv->publicValue.data[1], len);
2469 fputs(buf, ecdsaresp);
2470 fputc('\n', ecdsaresp);
2471 fputs("Qy = ", ecdsaresp);
2472 to_hex_str(buf, &ecpriv->publicValue.data[1 + len], len);
2473 fputs(buf, ecdsaresp);
2474 fputc('\n', ecdsaresp);
2475 fputc('\n', ecdsaresp);
2476 PORT_FreeArenaPORT_FreeArena_Util(ecpriv->ecParams.arena, PR_TRUE1);
2477 }
2478 continue;
2479 }
2480 }
2481loser:
2482 if (ecparams) {
2483 PORT_FreeArenaPORT_FreeArena_Util(ecparams->arena, PR_FALSE0);
2484 ecparams = NULL((void*)0);
2485 }
2486 fclose(ecdsareq);
2487}
2488
2489/*
2490 * Perform the ECDSA Public Key Validation Test.
2491 *
2492 * reqfn is the pathname of the REQUEST file.
2493 *
2494 * The output RESPONSE file is written to stdout.
2495 */
2496void
2497ecdsa_pkv_test(char *reqfn)
2498{
2499 char buf[256]; /* holds one line from the input REQUEST file.
2500 * needs to be large enough to hold the longest
2501 * line "Qx = <144 hex digits>\n".
2502 */
2503 FILE *ecdsareq; /* input stream from the REQUEST file */
2504 FILE *ecdsaresp; /* output stream to the RESPONSE file */
2505 char curve[16]; /* "nistxddd" */
2506 ECParams *ecparams = NULL((void*)0);
2507 SECItem pubkey;
2508 unsigned int i;
2509 unsigned int len = 0;
2510 PRBool keyvalid = PR_TRUE1;
2511
2512 ecdsareq = fopen(reqfn, "r");
2513 ecdsaresp = stdoutstdout;
2514 strcpy(curve, "nist");
2515 pubkey.data = NULL((void*)0);
2516 while (fgets(buf, sizeof buf, ecdsareq) != NULL((void*)0)) {
2517 /* a comment or blank line */
2518 if (buf[0] == '#' || buf[0] == '\n') {
2519 fputs(buf, ecdsaresp);
2520 continue;
2521 }
2522 /* [X-ddd] */
2523 if (buf[0] == '[') {
2524 const char *src;
2525 char *dst;
2526 SECItem *encodedparams;
2527
2528 src = &buf[1];
2529 dst = &curve[4];
2530 *dst++ = tolower(*src);
2531 src += 2; /* skip the hyphen */
2532 *dst++ = *src++;
2533 *dst++ = *src++;
2534 *dst++ = *src++;
2535 *dst = '\0';
2536 if (ecparams != NULL((void*)0)) {
2537 PORT_FreeArenaPORT_FreeArena_Util(ecparams->arena, PR_FALSE0);
2538 ecparams = NULL((void*)0);
2539 }
2540 encodedparams = getECParams(curve);
2541 if (encodedparams == NULL((void*)0)) {
2542 fprintf(stderrstderr, "Unknown curve %s.", curve);
2543 goto loser;
2544 }
2545 if (EC_DecodeParams(encodedparams, &ecparams) != SECSuccess) {
2546 fprintf(stderrstderr, "Curve %s not supported.\n", curve);
2547 goto loser;
2548 }
2549 SECITEM_FreeItemSECITEM_FreeItem_Util(encodedparams, PR_TRUE1);
2550 len = (ecparams->fieldID.size + 7) >> 3;
2551 if (pubkey.data != NULL((void*)0)) {
2552 PORT_FreePORT_Free_Util(pubkey.data);
2553 pubkey.data = NULL((void*)0);
2554 }
2555 SECITEM_AllocItemSECITEM_AllocItem_Util(NULL((void*)0), &pubkey, EC_GetPointSize(ecparams));
2556 if (pubkey.data == NULL((void*)0)) {
2557 goto loser;
2558 }
2559 pubkey.data[0] = EC_POINT_FORM_UNCOMPRESSED0x04;
2560 fputs(buf, ecdsaresp);
2561 continue;
2562 }
2563 /* Qx = ... */
2564 if (strncmp(buf, "Qx", 2) == 0) {
2565 fputs(buf, ecdsaresp);
2566 i = 2;
2567 while (isspace(buf[i])((*__ctype_b_loc ())[(int) ((buf[i]))] & (unsigned short int
) _ISspace)
|| buf[i] == '=') {
2568 i++;
2569 }
2570 keyvalid = from_hex_str(&pubkey.data[1], len, &buf[i]);
2571 continue;
2572 }
2573 /* Qy = ... */
2574 if (strncmp(buf, "Qy", 2) == 0) {
2575 fputs(buf, ecdsaresp);
2576 if (!keyvalid) {
2577 fputs("Result = F\n", ecdsaresp);
2578 continue;
2579 }
2580 i = 2;
2581 while (isspace(buf[i])((*__ctype_b_loc ())[(int) ((buf[i]))] & (unsigned short int
) _ISspace)
|| buf[i] == '=') {
2582 i++;
2583 }
2584 keyvalid = from_hex_str(&pubkey.data[1 + len], len, &buf[i]);
2585 if (!keyvalid) {
2586 fputs("Result = F\n", ecdsaresp);
2587 continue;
2588 }
2589 if (EC_ValidatePublicKey(ecparams, &pubkey) == SECSuccess) {
2590 fputs("Result = P\n", ecdsaresp);
2591 } else if (PORT_GetErrorPORT_GetError_Util() == SEC_ERROR_BAD_KEY) {
2592 fputs("Result = F\n", ecdsaresp);
2593 } else {
2594 goto loser;
2595 }
2596 continue;
2597 }
2598 }
2599loser:
2600 if (ecparams != NULL((void*)0)) {
2601 PORT_FreeArenaPORT_FreeArena_Util(ecparams->arena, PR_FALSE0);
2602 }
2603 if (pubkey.data != NULL((void*)0)) {
2604 PORT_FreePORT_Free_Util(pubkey.data);
2605 }
2606 fclose(ecdsareq);
2607}
2608
2609/*
2610 * Perform the ECDSA Signature Generation Test.
2611 *
2612 * reqfn is the pathname of the REQUEST file.
2613 *
2614 * The output RESPONSE file is written to stdout.
2615 */
2616void
2617ecdsa_siggen_test(char *reqfn)
2618{
2619 char buf[1024]; /* holds one line from the input REQUEST file
2620 * or to the output RESPONSE file.
2621 * needs to be large enough to hold the longest
2622 * line "Msg = <256 hex digits>\n".
2623 */
2624 FILE *ecdsareq; /* input stream from the REQUEST file */
2625 FILE *ecdsaresp; /* output stream to the RESPONSE file */
2626 char curve[16]; /* "nistxddd" */
2627 ECParams *ecparams = NULL((void*)0);
2628 int i, j;
2629 unsigned int len;
2630 unsigned char msg[512]; /* message to be signed (<= 128 bytes) */
2631 unsigned int msglen;
2632 unsigned char sha[HASH_LENGTH_MAX64]; /* SHA digest */
2633 unsigned int shaLength = 0; /* length of SHA */
2634 HASH_HashType shaAlg = HASH_AlgNULL; /* type of SHA Alg */
2635 unsigned char sig[2 * MAX_ECKEY_LEN72];
2636 SECItem signature, digest;
2637
2638 ecdsareq = fopen(reqfn, "r");
2639 ecdsaresp = stdoutstdout;
2640 strcpy(curve, "nist");
2641 while (fgets(buf, sizeof buf, ecdsareq) != NULL((void*)0)) {
2642 /* a comment or blank line */
2643 if (buf[0] == '#' || buf[0] == '\n') {
2644 fputs(buf, ecdsaresp);
2645 continue;
2646 }
2647 /* [X-ddd] */
2648 if (buf[0] == '[') {
2649 const char *src;
2650 char *dst;
2651 SECItem *encodedparams;
2652
2653 src = &buf[1];
2654 dst = &curve[4];
2655 *dst++ = tolower(*src);
2656 src += 2; /* skip the hyphen */
2657 *dst++ = *src++;
2658 *dst++ = *src++;
2659 *dst++ = *src++;
2660 *dst = '\0';
2661 src++; /* skip the comma */
2662 /* set the SHA Algorithm */
2663 shaAlg = hash_string_to_hashType(src);
2664 if (shaAlg == HASH_AlgNULL) {
2665 fprintf(ecdsaresp, "ERROR: Unable to find SHAAlg type");
2666 goto loser;
2667 }
2668 if (ecparams != NULL((void*)0)) {
2669 PORT_FreeArenaPORT_FreeArena_Util(ecparams->arena, PR_FALSE0);
2670 ecparams = NULL((void*)0);
2671 }
2672 encodedparams = getECParams(curve);
2673 if (encodedparams == NULL((void*)0)) {
2674 fprintf(stderrstderr, "Unknown curve %s.", curve);
2675 goto loser;
2676 }
2677 if (EC_DecodeParams(encodedparams, &ecparams) != SECSuccess) {
2678 fprintf(stderrstderr, "Curve %s not supported.\n", curve);
2679 goto loser;
2680 }
2681 SECITEM_FreeItemSECITEM_FreeItem_Util(encodedparams, PR_TRUE1);
2682 fputs(buf, ecdsaresp);
2683 continue;
2684 }
2685 /* Msg = ... */
2686 if (strncmp(buf, "Msg", 3) == 0) {
2687 ECPrivateKey *ecpriv;
2688
2689 i = 3;
2690 while (isspace(buf[i])((*__ctype_b_loc ())[(int) ((buf[i]))] & (unsigned short int
) _ISspace)
|| buf[i] == '=') {
2691 i++;
2692 }
2693 for (j = 0; isxdigit(buf[i])((*__ctype_b_loc ())[(int) ((buf[i]))] & (unsigned short int
) _ISxdigit)
; i += 2, j++) {
2694 hex_to_byteval(&buf[i], &msg[j]);
2695 }
2696 msglen = j;
2697 shaLength = fips_hashLen(shaAlg);
2698 if (fips_hashBuf(shaAlg, sha, msg, msglen) != SECSuccess) {
2699 if (shaLength == 0) {
2700 fprintf(ecdsaresp, "ERROR: SHAAlg not defined.");
2701 }
2702 fprintf(ecdsaresp, "ERROR: Unable to generate SHA%x",
2703 shaLength == 160 ? 1 : shaLength);
2704 goto loser;
2705 }
2706 fputs(buf, ecdsaresp);
2707
2708 if (EC_NewKey(ecparams, &ecpriv) != SECSuccess) {
2709 goto loser;
2710 }
2711 if (EC_ValidatePublicKey(ecparams, &ecpriv->publicValue) !=
2712 SECSuccess) {
2713 goto loser;
2714 }
2715 len = ecpriv->publicValue.len;
2716 if (len % 2 == 0) {
2717 goto loser;
2718 }
2719 len = (len - 1) / 2;
2720 if (ecpriv->publicValue.data[0] != EC_POINT_FORM_UNCOMPRESSED0x04) {
2721 goto loser;
2722 }
2723 fputs("Qx = ", ecdsaresp);
2724 to_hex_str(buf, &ecpriv->publicValue.data[1], len);
2725 fputs(buf, ecdsaresp);
2726 fputc('\n', ecdsaresp);
2727 fputs("Qy = ", ecdsaresp);
2728 to_hex_str(buf, &ecpriv->publicValue.data[1 + len], len);
2729 fputs(buf, ecdsaresp);
2730 fputc('\n', ecdsaresp);
2731
2732 digest.type = siBuffer;
2733 digest.data = sha;
2734 digest.len = shaLength;
2735 signature.type = siBuffer;
2736 signature.data = sig;
2737 signature.len = sizeof sig;
2738 if (ECDSA_SignDigest(ecpriv, &signature, &digest) != SECSuccess) {
2739 goto loser;
2740 }
2741 len = signature.len;
2742 if (len % 2 != 0) {
2743 goto loser;
2744 }
2745 len = len / 2;
2746 fputs("R = ", ecdsaresp);
2747 to_hex_str(buf, &signature.data[0], len);
2748 fputs(buf, ecdsaresp);
2749 fputc('\n', ecdsaresp);
2750 fputs("S = ", ecdsaresp);
2751 to_hex_str(buf, &signature.data[len], len);
2752 fputs(buf, ecdsaresp);
2753 fputc('\n', ecdsaresp);
2754
2755 PORT_FreeArenaPORT_FreeArena_Util(ecpriv->ecParams.arena, PR_TRUE1);
2756 continue;
2757 }
2758 }
2759loser:
2760 if (ecparams != NULL((void*)0)) {
2761 PORT_FreeArenaPORT_FreeArena_Util(ecparams->arena, PR_FALSE0);
2762 }
2763 fclose(ecdsareq);
2764}
2765
2766/*
2767 * Perform the ECDSA Signature Verification Test.
2768 *
2769 * reqfn is the pathname of the REQUEST file.
2770 *
2771 * The output RESPONSE file is written to stdout.
2772 */
2773void
2774ecdsa_sigver_test(char *reqfn)
2775{
2776 char buf[1024]; /* holds one line from the input REQUEST file.
2777 * needs to be large enough to hold the longest
2778 * line "Msg = <256 hex digits>\n".
2779 */
2780 FILE *ecdsareq; /* input stream from the REQUEST file */
2781 FILE *ecdsaresp; /* output stream to the RESPONSE file */
2782 char curve[16]; /* "nistxddd" */
2783 ECPublicKey ecpub;
2784 unsigned int i, j;
2785 unsigned int flen = 0; /* length in bytes of the field size */
2786 unsigned int olen = 0; /* length in bytes of the base point order */
2787 unsigned char msg[512]; /* message that was signed (<= 128 bytes) */
2788 unsigned int msglen = 0;
2789 unsigned char sha[HASH_LENGTH_MAX64]; /* SHA digest */
2790 unsigned int shaLength = 0; /* length of SHA */
2791 HASH_HashType shaAlg = HASH_AlgNULL; /* type of SHA Alg */
2792 unsigned char sig[2 * MAX_ECKEY_LEN72];
2793 SECItem signature, digest;
2794 PRBool keyvalid = PR_TRUE1;
2795 PRBool sigvalid = PR_TRUE1;
2796
2797 ecdsareq = fopen(reqfn, "r");
2798 ecdsaresp = stdoutstdout;
2799 ecpub.ecParams.arena = NULL((void*)0);
2800 strcpy(curve, "nist");
2801 while (fgets(buf, sizeof buf, ecdsareq) != NULL((void*)0)) {
2802 /* a comment or blank line */
2803 if (buf[0] == '#' || buf[0] == '\n') {
2804 fputs(buf, ecdsaresp);
2805 continue;
2806 }
2807 /* [X-ddd] */
2808 if (buf[0] == '[') {
2809 const char *src;
2810 char *dst;
2811 SECItem *encodedparams;
2812 ECParams *ecparams;
2813
2814 src = &buf[1];
2815 dst = &curve[4];
2816 *dst++ = tolower(*src);
2817 src += 2; /* skip the hyphen */
2818 *dst++ = *src++;
2819 *dst++ = *src++;
2820 *dst++ = *src++;
2821 *dst = '\0';
2822 src++; /* skip the comma */
2823 /* set the SHA Algorithm */
2824 shaAlg = hash_string_to_hashType(src);
2825 if (shaAlg == HASH_AlgNULL) {
2826 fprintf(ecdsaresp, "ERROR: Unable to find SHAAlg type");
2827 goto loser;
2828 }
2829 encodedparams = getECParams(curve);
2830 if (encodedparams == NULL((void*)0)) {
2831 fprintf(stderrstderr, "Unknown curve %s.", curve);
2832 goto loser;
2833 }
2834 if (EC_DecodeParams(encodedparams, &ecparams) != SECSuccess) {
2835 fprintf(stderrstderr, "Curve %s not supported.\n", curve);
2836 goto loser;
2837 }
2838 SECITEM_FreeItemSECITEM_FreeItem_Util(encodedparams, PR_TRUE1);
2839 if (ecpub.ecParams.arena != NULL((void*)0)) {
2840 PORT_FreeArenaPORT_FreeArena_Util(ecpub.ecParams.arena, PR_FALSE0);
2841 }
2842 ecpub.ecParams.arena = PORT_NewArenaPORT_NewArena_Util(DER_DEFAULT_CHUNKSIZE(2048));
2843 if (ecpub.ecParams.arena == NULL((void*)0)) {
2844 goto loser;
2845 }
2846 if (EC_CopyParams(ecpub.ecParams.arena, &ecpub.ecParams, ecparams) !=
2847 SECSuccess) {
2848 goto loser;
2849 }
2850 PORT_FreeArenaPORT_FreeArena_Util(ecparams->arena, PR_FALSE0);
2851 flen = (ecpub.ecParams.fieldID.size + 7) >> 3;
2852 olen = ecpub.ecParams.order.len;
2853 if (2 * olen > sizeof sig) {
2854 goto loser;
2855 }
2856 ecpub.publicValue.type = siBuffer;
2857 ecpub.publicValue.data = NULL((void*)0);
2858 ecpub.publicValue.len = 0;
2859 SECITEM_AllocItemSECITEM_AllocItem_Util(ecpub.ecParams.arena,
2860 &ecpub.publicValue, 2 * flen + 1);
2861 if (ecpub.publicValue.data == NULL((void*)0)) {
2862 goto loser;
2863 }
2864 ecpub.publicValue.data[0] = EC_POINT_FORM_UNCOMPRESSED0x04;
2865 fputs(buf, ecdsaresp);
2866 continue;
2867 }
2868 /* Msg = ... */
2869 if (strncmp(buf, "Msg", 3) == 0) {
2870 i = 3;
2871 while (isspace(buf[i])((*__ctype_b_loc ())[(int) ((buf[i]))] & (unsigned short int
) _ISspace)
|| buf[i] == '=') {
2872 i++;
2873 }
2874 for (j = 0; isxdigit(buf[i])((*__ctype_b_loc ())[(int) ((buf[i]))] & (unsigned short int
) _ISxdigit)
; i += 2, j++) {
2875 hex_to_byteval(&buf[i], &msg[j]);
2876 }
2877 msglen = j;
2878 shaLength = fips_hashLen(shaAlg);
2879 if (fips_hashBuf(shaAlg, sha, msg, msglen) != SECSuccess) {
2880 if (shaLength == 0) {
2881 fprintf(ecdsaresp, "ERROR: SHAAlg not defined.");
2882 }
2883 fprintf(ecdsaresp, "ERROR: Unable to generate SHA%x",
2884 shaLength == 160 ? 1 : shaLength);
2885 goto loser;
2886 }
2887 fputs(buf, ecdsaresp);
2888
2889 digest.type = siBuffer;
2890 digest.data = sha;
2891 digest.len = shaLength;
2892
2893 continue;
2894 }
2895 /* Qx = ... */
2896 if (strncmp(buf, "Qx", 2) == 0) {
2897 fputs(buf, ecdsaresp);
2898 i = 2;
2899 while (isspace(buf[i])((*__ctype_b_loc ())[(int) ((buf[i]))] & (unsigned short int
) _ISspace)
|| buf[i] == '=') {
2900 i++;
2901 }
2902 keyvalid = from_hex_str(&ecpub.publicValue.data[1], flen,
2903 &buf[i]);
2904 continue;
2905 }
2906 /* Qy = ... */
2907 if (strncmp(buf, "Qy", 2) == 0) {
2908 fputs(buf, ecdsaresp);
2909 if (!keyvalid) {
2910 continue;
2911 }
2912 i = 2;
2913 while (isspace(buf[i])((*__ctype_b_loc ())[(int) ((buf[i]))] & (unsigned short int
) _ISspace)
|| buf[i] == '=') {
2914 i++;
2915 }
2916 keyvalid = from_hex_str(&ecpub.publicValue.data[1 + flen], flen,
2917 &buf[i]);
2918 if (!keyvalid) {
2919 continue;
2920 }
2921 if (EC_ValidatePublicKey(&ecpub.ecParams, &ecpub.publicValue) !=
2922 SECSuccess) {
2923 if (PORT_GetErrorPORT_GetError_Util() == SEC_ERROR_BAD_KEY) {
2924 keyvalid = PR_FALSE0;
2925 } else {
2926 goto loser;
2927 }
2928 }
2929 continue;
2930 }
2931 /* R = ... */
2932 if (buf[0] == 'R') {
2933 fputs(buf, ecdsaresp);
2934 i = 1;
2935 while (isspace(buf[i])((*__ctype_b_loc ())[(int) ((buf[i]))] & (unsigned short int
) _ISspace)
|| buf[i] == '=') {
2936 i++;
2937 }
2938 sigvalid = from_hex_str(sig, olen, &buf[i]);
2939 continue;
2940 }
2941 /* S = ... */
2942 if (buf[0] == 'S') {
2943 fputs(buf, ecdsaresp);
2944 i = 1;
2945 while (isspace(buf[i])((*__ctype_b_loc ())[(int) ((buf[i]))] & (unsigned short int
) _ISspace)
|| buf[i] == '=') {
2946 i++;
2947 }
2948 if (sigvalid) {
2949 sigvalid = from_hex_str(&sig[olen], olen, &buf[i]);
2950 }
2951 signature.type = siBuffer;
2952 signature.data = sig;
2953 signature.len = 2 * olen;
2954
2955 if (!keyvalid || !sigvalid) {
2956 fputs("Result = F\n", ecdsaresp);
2957 } else if (ECDSA_VerifyDigest(&ecpub, &signature, &digest) ==
2958 SECSuccess) {
2959 fputs("Result = P\n", ecdsaresp);
2960 } else {
2961 fputs("Result = F\n", ecdsaresp);
2962 }
2963 continue;
2964 }
2965 }
2966loser:
2967 if (ecpub.ecParams.arena != NULL((void*)0)) {
2968 PORT_FreeArenaPORT_FreeArena_Util(ecpub.ecParams.arena, PR_FALSE0);
2969 }
2970 fclose(ecdsareq);
2971}
2972
2973/*
2974 * Perform the ECDH Functional Test.
2975 *
2976 * reqfn is the pathname of the REQUEST file.
2977 *
2978 * The output RESPONSE file is written to stdout.
2979 */
2980#define MAX_ECC_PARAMS256 256
2981void
2982ecdh_functional(char *reqfn, PRBool response)
2983{
2984 char buf[256]; /* holds one line from the input REQUEST file.
2985 * needs to be large enough to hold the longest
2986 * line "Qx = <144 hex digits>\n".
2987 */
2988 FILE *ecdhreq; /* input stream from the REQUEST file */
2989 FILE *ecdhresp; /* output stream to the RESPONSE file */
2990 char curve[16]; /* "nistxddd" */
2991 unsigned char hashBuf[HASH_LENGTH_MAX64];
2992 ECParams *ecparams[MAX_ECC_PARAMS256] = { NULL((void*)0) };
2993 ECPrivateKey *ecpriv = NULL((void*)0);
2994 ECParams *current_ecparams = NULL((void*)0);
2995 SECItem pubkey;
2996 SECItem ZZ;
2997 unsigned int i;
2998 unsigned int len = 0;
2999 unsigned int uit_len = 0;
3000 int current_curve = -1;
3001 HASH_HashType hash = HASH_AlgNULL; /* type of SHA Alg */
3002
3003 ecdhreq = fopen(reqfn, "r");
3004 ecdhresp = stdoutstdout;
3005 strcpy(curve, "nist");
3006 pubkey.data = NULL((void*)0);
3007 while (fgets(buf, sizeof buf, ecdhreq) != NULL((void*)0)) {
3008 /* a comment or blank line */
3009 if (buf[0] == '#' || buf[0] == '\n' || buf[0] == '\r') {
3010 fputs(buf, ecdhresp);
3011 continue;
3012 }
3013 if (buf[0] == '[') {
3014 /* [Ex] */
3015 if (buf[1] == 'E' && buf[3] == ']') {
3016 current_curve = buf[2] - 'A';
3017 fputs(buf, ecdhresp);
3018 continue;
3019 }
3020 /* [Curve selected: x-nnn */
3021 if (strncmp(buf, "[Curve ", 7) == 0) {
3022 const char *src;
3023 char *dst;
3024 SECItem *encodedparams;
3025
3026 if ((current_curve < 0) || (current_curve > MAX_ECC_PARAMS256)) {
3027 fprintf(stderrstderr, "No curve type defined\n");
3028 goto loser;
3029 }
3030
3031 src = &buf[1];
3032 /* skip passed the colon */
3033 while (*src && *src != ':')
3034 src++;
3035 if (*src != ':') {
3036 fprintf(stderrstderr,
3037 "No colon in curve selected statement\n%s", buf);
3038 goto loser;
3039 }
3040 src++;
3041 /* skip to the first non-space */
3042 while (*src && *src == ' ')
3043 src++;
3044 dst = &curve[4];
3045 *dst++ = tolower(*src);
3046 src += 2; /* skip the hyphen */
3047 *dst++ = *src++;
3048 *dst++ = *src++;
3049 *dst++ = *src++;
3050 *dst = '\0';
3051 if (ecparams[current_curve] != NULL((void*)0)) {
3052 PORT_FreeArenaPORT_FreeArena_Util(ecparams[current_curve]->arena, PR_FALSE0);
3053 ecparams[current_curve] = NULL((void*)0);
3054 }
3055 encodedparams = getECParams(curve);
3056 if (encodedparams == NULL((void*)0)) {
3057 fprintf(stderrstderr, "Unknown curve %s.", curve);
3058 goto loser;
3059 }
3060 if (EC_DecodeParams(encodedparams, &ecparams[current_curve]) != SECSuccess) {
3061 fprintf(stderrstderr, "Curve %s not supported.\n", curve);
3062 goto loser;
3063 }
3064 SECITEM_FreeItemSECITEM_FreeItem_Util(encodedparams, PR_TRUE1);
3065 fputs(buf, ecdhresp);
3066 continue;
3067 }
3068 /* [Ex - SHAxxx] */
3069 if (buf[1] == 'E' && buf[3] == ' ') {
3070 const char *src;
3071 current_curve = buf[2] - 'A';
3072 if ((current_curve < 0) || (current_curve > 256)) {
3073 fprintf(stderrstderr, "bad curve type defined (%c)\n", buf[2]);
3074 goto loser;
3075 }
3076 current_ecparams = ecparams[current_curve];
3077 if (current_ecparams == NULL((void*)0)) {
3078 fprintf(stderrstderr, "no curve defined for type %c defined\n",
3079 buf[2]);
3080 goto loser;
3081 }
3082 /* skip passed the colon */
3083 src = &buf[1];
3084 while (*src && *src != '-')
3085 src++;
3086 if (*src != '-') {
3087 fprintf(stderrstderr,
3088 "No data in curve selected statement\n%s", buf);
3089 goto loser;
3090 }
3091 src++;
3092 /* skip to the first non-space */
3093 while (*src && *src == ' ')
3094 src++;
3095 hash = hash_string_to_hashType(src);
3096 if (hash == HASH_AlgNULL) {
3097 fprintf(ecdhresp, "ERROR: Unable to find SHAAlg type");
3098 goto loser;
3099 }
3100 fputs(buf, ecdhresp);
3101 continue;
3102 }
3103 fputs(buf, ecdhresp);
3104 continue;
3105 }
3106 /* COUNT = ... */
3107 if (strncmp(buf, "COUNT", 5) == 0) {
3108 fputs(buf, ecdhresp);
3109 if (current_ecparams == NULL((void*)0)) {
3110 fprintf(stderrstderr, "no curve defined for type %c defined\n",
3111 buf[2]);
3112 goto loser;
3113 }
3114 len = (current_ecparams->fieldID.size + 7) >> 3;
3115 if (pubkey.data != NULL((void*)0)) {
3116 PORT_FreePORT_Free_Util(pubkey.data);
3117 pubkey.data = NULL((void*)0);
3118 }
3119 SECITEM_AllocItemSECITEM_AllocItem_Util(NULL((void*)0), &pubkey, EC_GetPointSize(current_ecparams));
3120 if (pubkey.data == NULL((void*)0)) {
3121 goto loser;
3122 }
3123 pubkey.data[0] = EC_POINT_FORM_UNCOMPRESSED0x04;
3124 continue;
3125 }
3126 /* QeCAVSx = ... */
3127 if (strncmp(buf, "QeCAVSx", 7) == 0) {
3128 fputs(buf, ecdhresp);
3129 i = 7;
3130 while (isspace(buf[i])((*__ctype_b_loc ())[(int) ((buf[i]))] & (unsigned short int
) _ISspace)
|| buf[i] == '=') {
3131 i++;
3132 }
3133 from_hex_str(&pubkey.data[1], len, &buf[i]);
3134 continue;
3135 }
3136 /* QeCAVSy = ... */
3137 if (strncmp(buf, "QeCAVSy", 7) == 0) {
3138 fputs(buf, ecdhresp);
3139 i = 7;
3140 while (isspace(buf[i])((*__ctype_b_loc ())[(int) ((buf[i]))] & (unsigned short int
) _ISspace)
|| buf[i] == '=') {
3141 i++;
3142 }
3143 from_hex_str(&pubkey.data[1 + len], len, &buf[i]);
3144 if (current_ecparams == NULL((void*)0)) {
3145 fprintf(stderrstderr, "no curve defined\n");
3146 goto loser;
3147 }
3148 /* validate CAVS public key */
3149 if (EC_ValidatePublicKey(current_ecparams, &pubkey) != SECSuccess) {
3150 fprintf(stderrstderr, "BAD key detected\n");
3151 goto loser;
3152 }
3153
3154 /* generate ECC key pair */
3155 if (EC_NewKey(current_ecparams, &ecpriv) != SECSuccess) {
3156 fprintf(stderrstderr, "Failed to generate new key\n");
3157 goto loser;
3158 }
3159 /* validate UIT generated public key */
3160 if (EC_ValidatePublicKey(current_ecparams, &ecpriv->publicValue) !=
3161 SECSuccess) {
3162 fprintf(stderrstderr, "generate key did not validate\n");
3163 goto loser;
3164 }
3165 /* output UIT public key */
3166 uit_len = ecpriv->publicValue.len;
3167 if (uit_len % 2 == 0) {
3168 fprintf(stderrstderr, "generate key had invalid public value len\n");
3169 goto loser;
3170 }
3171 uit_len = (uit_len - 1) / 2;
3172 if (ecpriv->publicValue.data[0] != EC_POINT_FORM_UNCOMPRESSED0x04) {
3173 fprintf(stderrstderr, "generate key was compressed\n");
3174 goto loser;
3175 }
3176 fputs("deIUT = ", ecdhresp);
3177 to_hex_str(buf, ecpriv->privateValue.data, ecpriv->privateValue.len);
3178 fputs(buf, ecdhresp);
3179 fputc('\n', ecdhresp);
3180 fputs("QeIUTx = ", ecdhresp);
3181 to_hex_str(buf, &ecpriv->publicValue.data[1], uit_len);
3182 fputs(buf, ecdhresp);
3183 fputc('\n', ecdhresp);
3184 fputs("QeIUTy = ", ecdhresp);
3185 to_hex_str(buf, &ecpriv->publicValue.data[1 + uit_len], uit_len);
3186 fputs(buf, ecdhresp);
3187 fputc('\n', ecdhresp);
3188 /* ECDH */
3189 if (ECDH_Derive(&pubkey, current_ecparams, &ecpriv->privateValue,
3190 PR_FALSE0, &ZZ) != SECSuccess) {
3191 fprintf(stderrstderr, "Derive failed\n");
3192 goto loser;
3193 }
3194 /* output hash of ZZ */
3195 if (fips_hashBuf(hash, hashBuf, ZZ.data, ZZ.len) != SECSuccess) {
3196 fprintf(stderrstderr, "hash of derived key failed\n");
3197 goto loser;
3198 }
3199 SECITEM_FreeItemSECITEM_FreeItem_Util(&ZZ, PR_FALSE0);
3200 fputs("HashZZ = ", ecdhresp);
3201 to_hex_str(buf, hashBuf, fips_hashLen(hash));
3202 fputs(buf, ecdhresp);
3203 fputc('\n', ecdhresp);
3204 fputc('\n', ecdhresp);
3205 PORT_FreeArenaPORT_FreeArena_Util(ecpriv->ecParams.arena, PR_TRUE1);
3206 ecpriv = NULL((void*)0);
3207 continue;
3208 }
3209 }
3210loser:
3211 if (ecpriv != NULL((void*)0)) {
3212 PORT_FreeArenaPORT_FreeArena_Util(ecpriv->ecParams.arena, PR_TRUE1);
3213 }
3214 for (i = 0; i < MAX_ECC_PARAMS256; i++) {
3215 if (ecparams[i] != NULL((void*)0)) {
3216 PORT_FreeArenaPORT_FreeArena_Util(ecparams[i]->arena, PR_FALSE0);
3217 ecparams[i] = NULL((void*)0);
3218 }
3219 }
3220 if (pubkey.data != NULL((void*)0)) {
3221 PORT_FreePORT_Free_Util(pubkey.data);
3222 }
3223 fclose(ecdhreq);
3224}
3225
3226/*
3227 * Perform the ECDH Validity Test.
3228 *
3229 * reqfn is the pathname of the REQUEST file.
3230 *
3231 * The output RESPONSE file is written to stdout.
3232 */
3233void
3234ecdh_verify(char *reqfn, PRBool response)
3235{
3236 char buf[256]; /* holds one line from the input REQUEST file.
3237 * needs to be large enough to hold the longest
3238 * line "Qx = <144 hex digits>\n".
3239 */
3240 FILE *ecdhreq; /* input stream from the REQUEST file */
3241 FILE *ecdhresp; /* output stream to the RESPONSE file */
3242 char curve[16]; /* "nistxddd" */
3243 unsigned char hashBuf[HASH_LENGTH_MAX64];
3244 unsigned char cavsHashBuf[HASH_LENGTH_MAX64];
3245 unsigned char private_data[MAX_ECKEY_LEN72];
3246 ECParams *ecparams[MAX_ECC_PARAMS256] = { NULL((void*)0) };
3247 ECParams *current_ecparams = NULL((void*)0);
3248 SECItem pubkey;
3249 SECItem ZZ;
3250 SECItem private_value;
3251 unsigned int i;
3252 unsigned int len = 0;
3253 int current_curve = -1;
3254 HASH_HashType hash = HASH_AlgNULL; /* type of SHA Alg */
3255
3256 ecdhreq = fopen(reqfn, "r");
3257 ecdhresp = stdoutstdout;
3258 strcpy(curve, "nist");
3259 pubkey.data = NULL((void*)0);
3260 while (fgets(buf, sizeof buf, ecdhreq) != NULL((void*)0)) {
3261 /* a comment or blank line */
3262 if (buf[0] == '#' || buf[0] == '\n' || buf[0] == '\r') {
3263 fputs(buf, ecdhresp);
3264 continue;
3265 }
3266 if (buf[0] == '[') {
3267 /* [Ex] */
3268 if (buf[1] == 'E' && buf[3] == ']') {
3269 current_curve = buf[2] - 'A';
3270 fputs(buf, ecdhresp);
3271 continue;
3272 }
3273 /* [Curve selected: x-nnn */
3274 if (strncmp(buf, "[Curve ", 7) == 0) {
3275 const char *src;
3276 char *dst;
3277 SECItem *encodedparams;
3278
3279 if ((current_curve < 0) || (current_curve > MAX_ECC_PARAMS256)) {
3280 fprintf(stderrstderr, "No curve type defined\n");
3281 goto loser;
3282 }
3283
3284 src = &buf[1];
3285 /* skip passed the colon */
3286 while (*src && *src != ':')
3287 src++;
3288 if (*src != ':') {
3289 fprintf(stderrstderr,
3290 "No colon in curve selected statement\n%s", buf);
3291 goto loser;
3292 }
3293 src++;
3294 /* skip to the first non-space */
3295 while (*src && *src == ' ')
3296 src++;
3297 dst = &curve[4];
3298 *dst++ = tolower(*src);
3299 src += 2; /* skip the hyphen */
3300 *dst++ = *src++;
3301 *dst++ = *src++;
3302 *dst++ = *src++;
3303 *dst = '\0';
3304 if (ecparams[current_curve] != NULL((void*)0)) {
3305 PORT_FreeArenaPORT_FreeArena_Util(ecparams[current_curve]->arena, PR_FALSE0);
3306 ecparams[current_curve] = NULL((void*)0);
3307 }
3308 encodedparams = getECParams(curve);
3309 if (encodedparams == NULL((void*)0)) {
3310 fprintf(stderrstderr, "Unknown curve %s.\n", curve);
3311 goto loser;
3312 }
3313 if (EC_DecodeParams(encodedparams, &ecparams[current_curve]) != SECSuccess) {
3314 fprintf(stderrstderr, "Curve %s not supported.\n", curve);
3315 goto loser;
3316 }
3317 SECITEM_FreeItemSECITEM_FreeItem_Util(encodedparams, PR_TRUE1);
3318 fputs(buf, ecdhresp);
3319 continue;
3320 }
3321 /* [Ex - SHAxxx] */
3322 if (buf[1] == 'E' && buf[3] == ' ') {
3323 const char *src;
3324 current_curve = buf[2] - 'A';
3325 if ((current_curve < 0) || (current_curve > 256)) {
3326 fprintf(stderrstderr, "bad curve type defined (%c)\n", buf[2]);
3327 goto loser;
3328 }
3329 current_ecparams = ecparams[current_curve];
3330 if (current_ecparams == NULL((void*)0)) {
3331 fprintf(stderrstderr, "no curve defined for type %c defined\n",
3332 buf[2]);
3333 goto loser;
3334 }
3335 /* skip passed the colon */
3336 src = &buf[1];
3337 while (*src && *src != '-')
3338 src++;
3339 if (*src != '-') {
3340 fprintf(stderrstderr,
3341 "No data in curve selected statement\n%s", buf);
3342 goto loser;
3343 }
3344 src++;
3345 /* skip to the first non-space */
3346 while (*src && *src == ' ')
3347 src++;
3348 hash = hash_string_to_hashType(src);
3349 if (hash == HASH_AlgNULL) {
3350 fprintf(ecdhresp, "ERROR: Unable to find SHAAlg type");
3351 goto loser;
3352 }
3353 fputs(buf, ecdhresp);
3354 continue;
3355 }
3356 fputs(buf, ecdhresp);
3357 continue;
3358 }
3359 /* COUNT = ... */
3360 if (strncmp(buf, "COUNT", 5) == 0) {
3361 fputs(buf, ecdhresp);
3362 if (current_ecparams == NULL((void*)0)) {
3363 fprintf(stderrstderr, "no curve defined for type %c defined\n",
3364 buf[2]);
3365 goto loser;
3366 }
3367 len = (current_ecparams->fieldID.size + 7) >> 3;
3368 if (pubkey.data != NULL((void*)0)) {
3369 PORT_FreePORT_Free_Util(pubkey.data);
3370 pubkey.data = NULL((void*)0);
3371 }
3372 SECITEM_AllocItemSECITEM_AllocItem_Util(NULL((void*)0), &pubkey, EC_GetPointSize(current_ecparams));
3373 if (pubkey.data == NULL((void*)0)) {
3374 goto loser;
3375 }
3376 pubkey.data[0] = EC_POINT_FORM_UNCOMPRESSED0x04;
3377 continue;
3378 }
3379 /* QeCAVSx = ... */
3380 if (strncmp(buf, "QeCAVSx", 7) == 0) {
3381 fputs(buf, ecdhresp);
3382 i = 7;
3383 while (isspace(buf[i])((*__ctype_b_loc ())[(int) ((buf[i]))] & (unsigned short int
) _ISspace)
|| buf[i] == '=') {
3384 i++;
3385 }
3386 from_hex_str(&pubkey.data[1], len, &buf[i]);
3387 continue;
3388 }
3389 /* QeCAVSy = ... */
3390 if (strncmp(buf, "QeCAVSy", 7) == 0) {
3391 fputs(buf, ecdhresp);
3392 i = 7;
3393 while (isspace(buf[i])((*__ctype_b_loc ())[(int) ((buf[i]))] & (unsigned short int
) _ISspace)
|| buf[i] == '=') {
3394 i++;
3395 }
3396 from_hex_str(&pubkey.data[1 + len], len, &buf[i]);
3397 continue;
3398 }
3399 if (strncmp(buf, "deIUT", 5) == 0) {
3400 fputs(buf, ecdhresp);
3401 i = 5;
3402 while (isspace(buf[i])((*__ctype_b_loc ())[(int) ((buf[i]))] & (unsigned short int
) _ISspace)
|| buf[i] == '=') {
3403 i++;
3404 }
3405 from_hex_str(private_data, len, &buf[i]);
3406 private_value.data = private_data;
3407 private_value.len = len;
3408 continue;
3409 }
3410 if (strncmp(buf, "QeIUTx", 6) == 0) {
3411 fputs(buf, ecdhresp);
3412 continue;
3413 }
3414 if (strncmp(buf, "QeIUTy", 6) == 0) {
3415 fputs(buf, ecdhresp);
3416 continue;
3417 }
3418 if ((strncmp(buf, "CAVSHashZZ", 10) == 0) ||
3419 (strncmp(buf, "HashZZ", 6) == 0)) {
3420 fputs(buf, ecdhresp);
3421 i = (buf[0] == 'C') ? 10 : 6;
3422 while (isspace(buf[i])((*__ctype_b_loc ())[(int) ((buf[i]))] & (unsigned short int
) _ISspace)
|| buf[i] == '=') {
3423 i++;
3424 }
3425 from_hex_str(cavsHashBuf, fips_hashLen(hash), &buf[i]);
3426 if (current_ecparams == NULL((void*)0)) {
3427 fprintf(stderrstderr, "no curve defined for type defined\n");
3428 goto loser;
3429 }
3430 /* validate CAVS public key */
3431 if (EC_ValidatePublicKey(current_ecparams, &pubkey) != SECSuccess) {
3432#ifdef VERBOSE_REASON
3433 fprintf(ecdhresp, "Result = F # key didn't validate\n");
3434#else
3435 fprintf(ecdhresp, "Result = F\n");
3436#endif
3437 continue;
3438 }
3439
3440 /* ECDH */
3441 if (ECDH_Derive(&pubkey, current_ecparams, &private_value,
3442 PR_FALSE0, &ZZ) != SECSuccess) {
3443#ifdef VERBOSE_REASON
3444 fprintf(ecdhresp, "Result = F # derive failure\n");
3445#else
3446 fprintf(ecdhresp, "Result = F\n");
3447#endif
3448 continue;
3449 }
3450/* output ZZ */
3451#ifndef MATCH_OPENSSL1
3452 fputs("Z = ", ecdhresp);
3453 to_hex_str(buf, ZZ.data, ZZ.len);
3454 fputs(buf, ecdhresp);
3455 fputc('\n', ecdhresp);
3456#endif
3457
3458 if (fips_hashBuf(hash, hashBuf, ZZ.data, ZZ.len) != SECSuccess) {
3459 fprintf(stderrstderr, "hash of derived key failed\n");
3460 goto loser;
3461 }
3462 SECITEM_FreeItemSECITEM_FreeItem_Util(&ZZ, PR_FALSE0);
3463#ifndef MATCH_NIST
3464 fputs("IUTHashZZ = ", ecdhresp);
3465 to_hex_str(buf, hashBuf, fips_hashLen(hash));
3466 fputs(buf, ecdhresp);
3467 fputc('\n', ecdhresp);
3468#endif
3469 if (memcmp(hashBuf, cavsHashBuf, fips_hashLen(hash)) != 0) {
3470#ifdef VERBOSE_REASON
3471 fprintf(ecdhresp, "Result = F # hash doesn't match\n");
3472#else
3473 fprintf(ecdhresp, "Result = F\n");
3474#endif
3475 } else {
3476 fprintf(ecdhresp, "Result = P\n");
3477 }
3478#ifndef MATCH_OPENSSL1
3479 fputc('\n', ecdhresp);
3480#endif
3481 continue;
3482 }
3483 }
3484loser:
3485 for (i = 0; i < MAX_ECC_PARAMS256; i++) {
3486 if (ecparams[i] != NULL((void*)0)) {
3487 PORT_FreeArenaPORT_FreeArena_Util(ecparams[i]->arena, PR_FALSE0);
3488 ecparams[i] = NULL((void*)0);
3489 }
3490 }
3491 if (pubkey.data != NULL((void*)0)) {
3492 PORT_FreePORT_Free_Util(pubkey.data);
3493 }
3494 fclose(ecdhreq);
3495}
3496
3497/*
3498 * Perform the DH Functional Test.
3499 *
3500 * reqfn is the pathname of the REQUEST file.
3501 *
3502 * The output RESPONSE file is written to stdout.
3503 */
3504#define MAX_ECC_PARAMS256 256
3505void
3506dh_functional(char *reqfn, PRBool response)
3507{
3508 char buf[1024]; /* holds one line from the input REQUEST file.
3509 * needs to be large enough to hold the longest
3510 * line "YephCAVS = <512 hex digits>\n".
3511 */
3512 FILE *dhreq; /* input stream from the REQUEST file */
3513 FILE *dhresp; /* output stream to the RESPONSE file */
3514 unsigned char hashBuf[HASH_LENGTH_MAX64];
3515 DSAPrivateKey *dsapriv = NULL((void*)0);
3516 PQGParams pqg = { 0 };
3517 unsigned char pubkeydata[DSA_MAX_P_BITS3072 / 8];
3518 SECItem pubkey;
3519 SECItem ZZ;
3520 unsigned int i, j;
3521 unsigned int pgySize;
3522 HASH_HashType hash = HASH_AlgNULL; /* type of SHA Alg */
3523
3524 dhreq = fopen(reqfn, "r");
3525 dhresp = stdoutstdout;
3526 while (fgets(buf, sizeof buf, dhreq) != NULL((void*)0)) {
3527 /* a comment or blank line */
3528 if (buf[0] == '#' || buf[0] == '\n' || buf[0] == '\r') {
3529 fputs(buf, dhresp);
3530 continue;
3531 }
3532 if (buf[0] == '[') {
3533 /* [Fx - SHAxxx] */
3534 if (buf[1] == 'F' && buf[3] == ' ') {
3535 const char *src;
3536 /* skip passed the colon */
3537 src = &buf[1];
3538 while (*src && *src != '-')
3539 src++;
3540 if (*src != '-') {
3541 fprintf(stderrstderr, "No hash specified\n%s", buf);
3542 goto loser;
3543 }
3544 src++;
3545 /* skip to the first non-space */
3546 while (*src && *src == ' ')
3547 src++;
3548 hash = hash_string_to_hashType(src);
3549 if (hash == HASH_AlgNULL) {
3550 fprintf(dhresp, "ERROR: Unable to find SHAAlg type");
3551 goto loser;
3552 }
3553 /* clear the PQG parameters */
3554 if (pqg.prime.data) { /* P */
3555 SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(&pqg.prime, PR_FALSE0);
3556 }
3557 if (pqg.subPrime.data) { /* Q */
3558 SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(&pqg.subPrime, PR_FALSE0);
3559 }
3560 if (pqg.base.data) { /* G */
3561 SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(&pqg.base, PR_FALSE0);
3562 }
3563 pgySize = DSA_MAX_P_BITS3072 / 8; /* change if more key sizes are supported in CAVS */
3564 SECITEM_AllocItemSECITEM_AllocItem_Util(NULL((void*)0), &pqg.prime, pgySize);
3565 SECITEM_AllocItemSECITEM_AllocItem_Util(NULL((void*)0), &pqg.base, pgySize);
3566 pqg.prime.len = pqg.base.len = pgySize;
3567
3568 /* set q to the max allows */
3569 SECITEM_AllocItemSECITEM_AllocItem_Util(NULL((void*)0), &pqg.subPrime, DSA_MAX_Q_BITS256 / 8);
3570 pqg.subPrime.len = DSA_MAX_Q_BITS256 / 8;
3571 fputs(buf, dhresp);
3572 continue;
3573 }
3574 fputs(buf, dhresp);
3575 continue;
3576 }
3577 if (buf[0] == 'P') {
3578 i = 1;
3579 while (isspace(buf[i])((*__ctype_b_loc ())[(int) ((buf[i]))] & (unsigned short int
) _ISspace)
|| buf[i] == '=') {
3580 i++;
3581 }
3582 for (j = 0; j < pqg.prime.len; i += 2, j++) {
3583 if (!isxdigit(buf[i])((*__ctype_b_loc ())[(int) ((buf[i]))] & (unsigned short int
) _ISxdigit)
) {
3584 pqg.prime.len = j;
3585 break;
3586 }
3587 hex_to_byteval(&buf[i], &pqg.prime.data[j]);
3588 }
3589
3590 fputs(buf, dhresp);
3591 continue;
3592 }
3593
3594 /* Q = ... */
3595 if (buf[0] == 'Q') {
3596 i = 1;
3597 while (isspace(buf[i])((*__ctype_b_loc ())[(int) ((buf[i]))] & (unsigned short int
) _ISspace)
|| buf[i] == '=') {
3598 i++;
3599 }
3600 for (j = 0; j < pqg.subPrime.len; i += 2, j++) {
3601 if (!isxdigit(buf[i])((*__ctype_b_loc ())[(int) ((buf[i]))] & (unsigned short int
) _ISxdigit)
) {
3602 pqg.subPrime.len = j;
3603 break;
3604 }
3605 hex_to_byteval(&buf[i], &pqg.subPrime.data[j]);
3606 }
3607
3608 fputs(buf, dhresp);
3609 continue;
3610 }
3611
3612 /* G = ... */
3613 if (buf[0] == 'G') {
3614 i = 1;
3615 while (isspace(buf[i])((*__ctype_b_loc ())[(int) ((buf[i]))] & (unsigned short int
) _ISspace)
|| buf[i] == '=') {
3616 i++;
3617 }
3618 for (j = 0; j < pqg.base.len; i += 2, j++) {
3619 if (!isxdigit(buf[i])((*__ctype_b_loc ())[(int) ((buf[i]))] & (unsigned short int
) _ISxdigit)
) {
3620 pqg.base.len = j;
3621 break;
3622 }
3623 hex_to_byteval(&buf[i], &pqg.base.data[j]);
3624 }
3625
3626 fputs(buf, dhresp);
3627 continue;
3628 }
3629
3630 /* COUNT = ... */
3631 if (strncmp(buf, "COUNT", 5) == 0) {
3632 fputs(buf, dhresp);
3633 continue;
3634 }
3635
3636 /* YephemCAVS = ... */
3637 if (strncmp(buf, "YephemCAVS", 10) == 0) {
3638 fputs(buf, dhresp);
3639 i = 10;
3640 while (isspace(buf[i])((*__ctype_b_loc ())[(int) ((buf[i]))] & (unsigned short int
) _ISspace)
|| buf[i] == '=') {
3641 i++;
3642 }
3643 from_hex_str(pubkeydata, pqg.prime.len, &buf[i]);
3644 pubkey.data = pubkeydata;
3645 pubkey.len = pqg.prime.len;
3646
3647 /* generate FCC key pair, nist uses pqg rather then pg,
3648 * so use DSA to generate the key */
3649 if (DSA_NewKey(&pqg, &dsapriv) != SECSuccess) {
3650 fprintf(stderrstderr, "Failed to generate new key\n");
3651 goto loser;
3652 }
3653 fputs("XephemIUT = ", dhresp);
3654 to_hex_str(buf, dsapriv->privateValue.data, dsapriv->privateValue.len);
3655 fputs(buf, dhresp);
3656 fputc('\n', dhresp);
3657 fputs("YephemIUT = ", dhresp);
3658 to_hex_str(buf, dsapriv->publicValue.data, dsapriv->publicValue.len);
3659 fputs(buf, dhresp);
3660 fputc('\n', dhresp);
3661 /* DH */
3662 if (DH_Derive(&pubkey, &pqg.prime, &dsapriv->privateValue,
3663 &ZZ, pqg.prime.len) != SECSuccess) {
3664 fprintf(stderrstderr, "Derive failed\n");
3665 goto loser;
3666 }
3667 /* output hash of ZZ */
3668 if (fips_hashBuf(hash, hashBuf, ZZ.data, ZZ.len) != SECSuccess) {
3669 fprintf(stderrstderr, "hash of derived key failed\n");
3670 goto loser;
3671 }
3672 SECITEM_FreeItemSECITEM_FreeItem_Util(&ZZ, PR_FALSE0);
3673 fputs("HashZZ = ", dhresp);
3674 to_hex_str(buf, hashBuf, fips_hashLen(hash));
3675 fputs(buf, dhresp);
3676 fputc('\n', dhresp);
3677 fputc('\n', dhresp);
3678 PORT_FreeArenaPORT_FreeArena_Util(dsapriv->params.arena, PR_TRUE1);
3679 dsapriv = NULL((void*)0);
3680 continue;
3681 }
3682 }
3683loser:
3684 if (dsapriv != NULL((void*)0)) {
3685 PORT_FreeArenaPORT_FreeArena_Util(dsapriv->params.arena, PR_TRUE1);
3686 }
3687 fclose(dhreq);
3688}
3689
3690/*
3691 * Perform the DH Validity Test.
3692 *
3693 * reqfn is the pathname of the REQUEST file.
3694 *
3695 * The output RESPONSE file is written to stdout.
3696 */
3697void
3698dh_verify(char *reqfn, PRBool response)
3699{
3700 char buf[1024]; /* holds one line from the input REQUEST file.
3701 * needs to be large enough to hold the longest
3702 * line "YephCAVS = <512 hex digits>\n".
3703 */
3704 FILE *dhreq; /* input stream from the REQUEST file */
3705 FILE *dhresp; /* output stream to the RESPONSE file */
3706 unsigned char hashBuf[HASH_LENGTH_MAX64];
3707 unsigned char cavsHashBuf[HASH_LENGTH_MAX64];
3708 PQGParams pqg = { 0 };
3709 unsigned char pubkeydata[DSA_MAX_P_BITS3072 / 8];
3710 unsigned char privkeydata[DSA_MAX_P_BITS3072 / 8];
3711 SECItem pubkey;
3712 SECItem privkey;
3713 SECItem ZZ;
3714 unsigned int i, j;
3715 unsigned int pgySize;
3716 HASH_HashType hash = HASH_AlgNULL; /* type of SHA Alg */
3717
3718 dhreq = fopen(reqfn, "r");
3719 dhresp = stdoutstdout;
3720 while (fgets(buf, sizeof buf, dhreq) != NULL((void*)0)) {
3721 /* a comment or blank line */
3722 if (buf[0] == '#' || buf[0] == '\n' || buf[0] == '\r') {
3723 fputs(buf, dhresp);
3724 continue;
3725 }
3726 if (buf[0] == '[') {
3727 /* [Fx - SHAxxx] */
3728 if (buf[1] == 'F' && buf[3] == ' ') {
3729 const char *src;
3730 /* skip passed the colon */
3731 src = &buf[1];
3732 while (*src && *src != '-')
3733 src++;
3734 if (*src != '-') {
3735 fprintf(stderrstderr, "No hash specified\n%s", buf);
3736 goto loser;
3737 }
3738 src++;
3739 /* skip to the first non-space */
3740 while (*src && *src == ' ')
3741 src++;
3742 hash = hash_string_to_hashType(src);
3743 if (hash == HASH_AlgNULL) {
3744 fprintf(dhresp, "ERROR: Unable to find SHAAlg type");
3745 goto loser;
3746 }
3747 /* clear the PQG parameters */
3748 if (pqg.prime.data) { /* P */
3749 SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(&pqg.prime, PR_FALSE0);
3750 }
3751 if (pqg.subPrime.data) { /* Q */
3752 SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(&pqg.subPrime, PR_FALSE0);
3753 }
3754 if (pqg.base.data) { /* G */
3755 SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(&pqg.base, PR_FALSE0);
3756 }
3757 pgySize = DSA_MAX_P_BITS3072 / 8; /* change if more key sizes are supported in CAVS */
3758 SECITEM_AllocItemSECITEM_AllocItem_Util(NULL((void*)0), &pqg.prime, pgySize);
3759 SECITEM_AllocItemSECITEM_AllocItem_Util(NULL((void*)0), &pqg.base, pgySize);
3760 pqg.prime.len = pqg.base.len = pgySize;
3761
3762 /* set q to the max allows */
3763 SECITEM_AllocItemSECITEM_AllocItem_Util(NULL((void*)0), &pqg.subPrime, DSA_MAX_Q_BITS256 / 8);
3764 pqg.subPrime.len = DSA_MAX_Q_BITS256 / 8;
3765 fputs(buf, dhresp);
3766 continue;
3767 }
3768 fputs(buf, dhresp);
3769 continue;
3770 }
3771 if (buf[0] == 'P') {
3772 i = 1;
3773 while (isspace(buf[i])((*__ctype_b_loc ())[(int) ((buf[i]))] & (unsigned short int
) _ISspace)
|| buf[i] == '=') {
3774 i++;
3775 }
3776 for (j = 0; j < pqg.prime.len; i += 2, j++) {
3777 if (!isxdigit(buf[i])((*__ctype_b_loc ())[(int) ((buf[i]))] & (unsigned short int
) _ISxdigit)
) {
3778 pqg.prime.len = j;
3779 break;
3780 }
3781 hex_to_byteval(&buf[i], &pqg.prime.data[j]);
3782 }
3783
3784 fputs(buf, dhresp);
3785 continue;
3786 }
3787
3788 /* Q = ... */
3789 if (buf[0] == 'Q') {
3790 i = 1;
3791 while (isspace(buf[i])((*__ctype_b_loc ())[(int) ((buf[i]))] & (unsigned short int
) _ISspace)
|| buf[i] == '=') {
3792 i++;
3793 }
3794 for (j = 0; j < pqg.subPrime.len; i += 2, j++) {
3795 if (!isxdigit(buf[i])((*__ctype_b_loc ())[(int) ((buf[i]))] & (unsigned short int
) _ISxdigit)
) {
3796 pqg.subPrime.len = j;
3797 break;
3798 }
3799 hex_to_byteval(&buf[i], &pqg.subPrime.data[j]);
3800 }
3801
3802 fputs(buf, dhresp);
3803 continue;
3804 }
3805
3806 /* G = ... */
3807 if (buf[0] == 'G') {
3808 i = 1;
3809 while (isspace(buf[i])((*__ctype_b_loc ())[(int) ((buf[i]))] & (unsigned short int
) _ISspace)
|| buf[i] == '=') {
3810 i++;
3811 }
3812 for (j = 0; j < pqg.base.len; i += 2, j++) {
3813 if (!isxdigit(buf[i])((*__ctype_b_loc ())[(int) ((buf[i]))] & (unsigned short int
) _ISxdigit)
) {
3814 pqg.base.len = j;
3815 break;
3816 }
3817 hex_to_byteval(&buf[i], &pqg.base.data[j]);
3818 }
3819
3820 fputs(buf, dhresp);
3821 continue;
3822 }
3823
3824 /* COUNT = ... */
3825 if (strncmp(buf, "COUNT", 5) == 0) {
3826 fputs(buf, dhresp);
3827 continue;
3828 }
3829
3830 /* YephemCAVS = ... */
3831 if (strncmp(buf, "YephemCAVS", 10) == 0) {
3832 fputs(buf, dhresp);
3833 i = 10;
3834 while (isspace(buf[i])((*__ctype_b_loc ())[(int) ((buf[i]))] & (unsigned short int
) _ISspace)
|| buf[i] == '=') {
3835 i++;
3836 }
3837 from_hex_str(pubkeydata, pqg.prime.len, &buf[i]);
3838 pubkey.data = pubkeydata;
3839 pubkey.len = pqg.prime.len;
3840 continue;
3841 }
3842 /* XephemUIT = ... */
3843 if (strncmp(buf, "XephemIUT", 9) == 0) {
3844 fputs(buf, dhresp);
3845 i = 9;
3846 while (isspace(buf[i])((*__ctype_b_loc ())[(int) ((buf[i]))] & (unsigned short int
) _ISspace)
|| buf[i] == '=') {
3847 i++;
3848 }
3849 from_hex_str(privkeydata, pqg.subPrime.len, &buf[i]);
3850 privkey.data = privkeydata;
3851 privkey.len = pqg.subPrime.len;
3852 continue;
3853 }
3854 /* YephemUIT = ... */
3855 if (strncmp(buf, "YephemIUT", 9) == 0) {
3856 fputs(buf, dhresp);
3857 continue;
3858 }
3859 /* CAVSHashZZ = ... */
3860 if ((strncmp(buf, "CAVSHashZZ", 10) == 0) ||
3861 (strncmp(buf, "HashZZ", 6) == 0)) {
3862 fputs(buf, dhresp);
3863 i = buf[0] == 'C' ? 10 : 6;
3864 while (isspace(buf[i])((*__ctype_b_loc ())[(int) ((buf[i]))] & (unsigned short int
) _ISspace)
|| buf[i] == '=') {
3865 i++;
3866 }
3867 from_hex_str(cavsHashBuf, fips_hashLen(hash), &buf[i]);
3868 /* do the DH operation*/
3869 if (DH_Derive(&pubkey, &pqg.prime, &privkey,
3870 &ZZ, pqg.prime.len) != SECSuccess) {
3871 fprintf(stderrstderr, "Derive failed\n");
3872 goto loser;
3873 }
3874/* output ZZ */
3875#ifndef MATCH_OPENSSL1
3876 fputs("Z = ", dhresp);
3877 to_hex_str(buf, ZZ.data, ZZ.len);
3878 fputs(buf, dhresp);
3879 fputc('\n', dhresp);
3880#endif
3881 if (fips_hashBuf(hash, hashBuf, ZZ.data, ZZ.len) != SECSuccess) {
3882 fprintf(stderrstderr, "hash of derived key failed\n");
3883 goto loser;
3884 }
3885 SECITEM_FreeItemSECITEM_FreeItem_Util(&ZZ, PR_FALSE0);
3886#ifndef MATCH_NIST
3887 fputs("IUTHashZZ = ", dhresp);
3888 to_hex_str(buf, hashBuf, fips_hashLen(hash));
3889 fputs(buf, dhresp);
3890 fputc('\n', dhresp);
3891#endif
3892 if (memcmp(hashBuf, cavsHashBuf, fips_hashLen(hash)) != 0) {
3893 fprintf(dhresp, "Result = F\n");
3894 } else {
3895 fprintf(dhresp, "Result = P\n");
3896 }
3897#ifndef MATCH_OPENSSL1
3898 fputc('\n', dhresp);
3899#endif
3900 continue;
3901 }
3902 }
3903loser:
3904 fclose(dhreq);
3905}
3906
3907PRBool
3908isblankline(char *b)
3909{
3910 while (isspace(*b)((*__ctype_b_loc ())[(int) ((*b))] & (unsigned short int)
_ISspace)
)
3911 b++;
3912 if ((*b == '\n') || (*b == 0)) {
3913 return PR_TRUE1;
3914 }
3915 return PR_FALSE0;
3916}
3917
3918static int debug = 0;
3919
3920/*
3921 * Perform the Hash_DRBG (CAVS) for the RNG algorithm
3922 *
3923 * reqfn is the pathname of the REQUEST file.
3924 *
3925 * The output RESPONSE file is written to stdout.
3926 */
3927void
3928drbg(char *reqfn)
3929{
3930 char buf[2000]; /* test case has some very long lines, returned bits
3931 * as high as 800 bytes (6400 bits). That 1600 byte
3932 * plus a tag */
3933 char buf2[2000];
3934 FILE *rngreq; /* input stream from the REQUEST file */
3935 FILE *rngresp; /* output stream to the RESPONSE file */
3936
3937 unsigned int i, j;
3938#ifdef HANDLE_PREDICTION_RESISTANCE
3939 PRBool predictionResistance = PR_FALSE0;
3940#endif
3941 unsigned char *nonce = NULL((void*)0);
3942 int nonceLen = 0;
3943 unsigned char *personalizationString = NULL((void*)0);
3944 int personalizationStringLen = 0;
3945 unsigned char *additionalInput = NULL((void*)0);
3946 int additionalInputLen = 0;
3947 unsigned char *entropyInput = NULL((void*)0);
3948 int entropyInputLen = 0;
3949 unsigned char *predictedreturn_bytes = NULL((void*)0);
3950 unsigned char *return_bytes = NULL((void*)0);
3951 int return_bytes_len = 0;
3952 enum { NONE,
3953 INSTANTIATE,
3954 GENERATE,
3955 RESEED,
3956 RESULT } command =
3957 NONE;
3958 PRBool genResult = PR_FALSE0;
3959 SECStatus rv;
3960
3961 rngreq = fopen(reqfn, "r");
3962 rngresp = stdoutstdout;
3963 while (fgets(buf, sizeof buf, rngreq) != NULL((void*)0)) {
3964 switch (command) {
3965 case INSTANTIATE:
3966 if (debug) {
3967 fputs("# PRNGTEST_Instantiate(", rngresp);
3968 to_hex_str(buf2, entropyInput, entropyInputLen);
3969 fputs(buf2, rngresp);
3970 fprintf(rngresp, ",%d,", entropyInputLen);
3971 to_hex_str(buf2, nonce, nonceLen);
3972 fputs(buf2, rngresp);
3973 fprintf(rngresp, ",%d,", nonceLen);
3974 to_hex_str(buf2, personalizationString,
3975 personalizationStringLen);
3976 fputs(buf2, rngresp);
3977 fprintf(rngresp, ",%d)\n", personalizationStringLen);
3978 }
3979 rv = PRNGTEST_Instantiate(entropyInput, entropyInputLen,
3980 nonce, nonceLen,
3981 personalizationString,
3982 personalizationStringLen);
3983 if (rv != SECSuccess) {
3984 goto loser;
3985 }
3986 break;
3987
3988 case GENERATE:
3989 case RESULT:
3990 memset(return_bytes, 0, return_bytes_len);
3991 if (debug) {
3992 fputs("# PRNGTEST_Generate(returnbytes", rngresp);
3993 fprintf(rngresp, ",%d,", return_bytes_len);
3994 to_hex_str(buf2, additionalInput, additionalInputLen);
3995 fputs(buf2, rngresp);
3996 fprintf(rngresp, ",%d)\n", additionalInputLen);
3997 }
3998 rv = PRNGTEST_Generate((PRUint8 *)return_bytes,
3999 return_bytes_len,
4000 (PRUint8 *)additionalInput,
4001 additionalInputLen);
4002 if (rv != SECSuccess) {
4003 goto loser;
4004 }
4005
4006 if (command == RESULT) {
4007 fputs("ReturnedBits = ", rngresp);
4008 to_hex_str(buf2, return_bytes, return_bytes_len);
4009 fputs(buf2, rngresp);
4010 fputc('\n', rngresp);
4011 if (debug) {
4012 fputs("# PRNGTEST_Uninstantiate()\n", rngresp);
4013 }
4014 rv = PRNGTEST_Uninstantiate();
4015 if (rv != SECSuccess) {
4016 goto loser;
4017 }
4018 } else if (debug) {
4019 fputs("#ReturnedBits = ", rngresp);
4020 to_hex_str(buf2, return_bytes, return_bytes_len);
4021 fputs(buf2, rngresp);
4022 fputc('\n', rngresp);
4023 }
4024
4025 memset(additionalInput, 0, additionalInputLen);
4026 break;
4027
4028 case RESEED:
4029 if (entropyInput || additionalInput) {
4030 if (debug) {
4031 fputs("# PRNGTEST_Reseed(", rngresp);
4032 fprintf(rngresp, ",%d,", return_bytes_len);
4033 to_hex_str(buf2, entropyInput, entropyInputLen);
4034 fputs(buf2, rngresp);
4035 fprintf(rngresp, ",%d,", entropyInputLen);
4036 to_hex_str(buf2, additionalInput, additionalInputLen);
4037 fputs(buf2, rngresp);
4038 fprintf(rngresp, ",%d)\n", additionalInputLen);
4039 }
4040 rv = PRNGTEST_Reseed(entropyInput, entropyInputLen,
4041 additionalInput, additionalInputLen);
4042 if (rv != SECSuccess) {
4043 goto loser;
4044 }
4045 }
4046 memset(entropyInput, 0, entropyInputLen);
4047 memset(additionalInput, 0, additionalInputLen);
4048 break;
4049 case NONE:
4050 break;
4051 }
4052 command = NONE;
4053
4054 /* a comment or blank line */
4055 if (buf[0] == '#' || buf[0] == '\n' || buf[0] == '\r') {
4056 fputs(buf, rngresp);
4057 continue;
4058 }
4059
4060 /* [Hash - SHA256] */
4061 if (strncmp(buf, "[SHA-256]", 9) == 0) {
4062 fputs(buf, rngresp);
4063 continue;
4064 }
4065
4066 if (strncmp(buf, "[PredictionResistance", 21) == 0) {
4067#ifdef HANDLE_PREDICTION_RESISTANCE
4068 i = 21;
4069 while (isspace(buf[i])((*__ctype_b_loc ())[(int) ((buf[i]))] & (unsigned short int
) _ISspace)
|| buf[i] == '=') {
4070 i++;
4071 }
4072 if (strncmp(buf, "False", 5) == 0) {
4073 predictionResistance = PR_FALSE0;
4074 } else {
4075 predictionResistance = PR_TRUE1;
4076 }
4077#endif
4078
4079 fputs(buf, rngresp);
4080 continue;
4081 }
4082
4083 if (strncmp(buf, "[ReturnedBitsLen", 16) == 0) {
4084 if (return_bytes) {
4085 PORT_ZFreePORT_ZFree_Util(return_bytes, return_bytes_len);
4086 return_bytes = NULL((void*)0);
4087 }
4088 if (predictedreturn_bytes) {
4089 PORT_ZFreePORT_ZFree_Util(predictedreturn_bytes, return_bytes_len);
4090 predictedreturn_bytes = NULL((void*)0);
4091 }
4092 return_bytes_len = 0;
4093 if (sscanf(buf, "[ReturnedBitsLen = %d]", &return_bytes_len) != 1) {
4094 goto loser;
4095 }
4096 return_bytes_len = return_bytes_len / 8;
4097 if (return_bytes_len > 0) {
4098 return_bytes = PORT_AllocPORT_Alloc_Util(return_bytes_len);
4099 predictedreturn_bytes = PORT_AllocPORT_Alloc_Util(return_bytes_len);
4100 }
4101 fputs(buf, rngresp);
4102 continue;
4103 }
4104
4105 if (strncmp(buf, "[EntropyInputLen", 16) == 0) {
4106 if (entropyInput) {
4107 PORT_ZFreePORT_ZFree_Util(entropyInput, entropyInputLen);
4108 entropyInput = NULL((void*)0);
4109 entropyInputLen = 0;
4110 }
4111 if (sscanf(buf, "[EntropyInputLen = %d]", &entropyInputLen) != 1) {
4112 goto loser;
4113 }
4114 entropyInputLen = entropyInputLen / 8;
4115 if (entropyInputLen > 0) {
4116 entropyInput = PORT_AllocPORT_Alloc_Util(entropyInputLen);
4117 }
4118 fputs(buf, rngresp);
4119 continue;
4120 }
4121
4122 if (strncmp(buf, "[NonceLen", 9) == 0) {
4123 if (nonce) {
4124 PORT_ZFreePORT_ZFree_Util(nonce, nonceLen);
4125 nonce = NULL((void*)0);
4126 nonceLen = 0;
4127 }
4128
4129 if (sscanf(buf, "[NonceLen = %d]", &nonceLen) != 1) {
4130 goto loser;
4131 }
4132 nonceLen = nonceLen / 8;
4133 if (nonceLen > 0) {
4134 nonce = PORT_AllocPORT_Alloc_Util(nonceLen);
4135 }
4136 fputs(buf, rngresp);
4137 continue;
4138 }
4139
4140 if (strncmp(buf, "[PersonalizationStringLen", 16) == 0) {
4141 if (personalizationString) {
4142 PORT_ZFreePORT_ZFree_Util(personalizationString, personalizationStringLen);
4143 personalizationString = NULL((void*)0);
4144 personalizationStringLen = 0;
4145 }
4146
4147 if (sscanf(buf, "[PersonalizationStringLen = %d]", &personalizationStringLen) != 1) {
4148 goto loser;
4149 }
4150 personalizationStringLen = personalizationStringLen / 8;
4151 if (personalizationStringLen > 0) {
4152 personalizationString = PORT_AllocPORT_Alloc_Util(personalizationStringLen);
4153 }
4154 fputs(buf, rngresp);
4155
4156 continue;
4157 }
4158
4159 if (strncmp(buf, "[AdditionalInputLen", 16) == 0) {
4160 if (additionalInput) {
4161 PORT_ZFreePORT_ZFree_Util(additionalInput, additionalInputLen);
4162 additionalInput = NULL((void*)0);
4163 additionalInputLen = 0;
4164 }
4165
4166 if (sscanf(buf, "[AdditionalInputLen = %d]", &additionalInputLen) != 1) {
4167 goto loser;
4168 }
4169 additionalInputLen = additionalInputLen / 8;
4170 if (additionalInputLen > 0) {
4171 additionalInput = PORT_AllocPORT_Alloc_Util(additionalInputLen);
4172 }
4173 fputs(buf, rngresp);
4174 continue;
4175 }
4176
4177 if (strncmp(buf, "COUNT", 5) == 0) {
4178 /* zeroize the variables for the test with this data set */
4179 if (entropyInput) {
4180 memset(entropyInput, 0, entropyInputLen);
4181 }
4182 if (nonce) {
4183 memset(nonce, 0, nonceLen);
4184 }
4185 if (personalizationString) {
4186 memset(personalizationString, 0, personalizationStringLen);
4187 }
4188 if (additionalInput) {
4189 memset(additionalInput, 0, additionalInputLen);
4190 }
4191 genResult = PR_FALSE0;
4192
4193 fputs(buf, rngresp);
4194 continue;
4195 }
4196
4197 /* EntropyInputReseed = ... */
4198 if (strncmp(buf, "EntropyInputReseed", 18) == 0) {
4199 if (entropyInput) {
4200 memset(entropyInput, 0, entropyInputLen);
4201 i = 18;
4202 while (isspace(buf[i])((*__ctype_b_loc ())[(int) ((buf[i]))] & (unsigned short int
) _ISspace)
|| buf[i] == '=') {
4203 i++;
4204 }
4205
4206 for (j = 0; isxdigit(buf[i])((*__ctype_b_loc ())[(int) ((buf[i]))] & (unsigned short int
) _ISxdigit)
; i += 2, j++) { /*j<entropyInputLen*/
4207 hex_to_byteval(&buf[i], &entropyInput[j]);
4208 }
4209 }
4210 fputs(buf, rngresp);
4211 continue;
4212 }
4213
4214 /* AttionalInputReseed = ... */
4215 if (strncmp(buf, "AdditionalInputReseed", 21) == 0) {
4216 if (additionalInput) {
4217 memset(additionalInput, 0, additionalInputLen);
4218 i = 21;
4219 while (isspace(buf[i])((*__ctype_b_loc ())[(int) ((buf[i]))] & (unsigned short int
) _ISspace)
|| buf[i] == '=') {
4220 i++;
4221 }
4222 for (j = 0; isxdigit(buf[i])((*__ctype_b_loc ())[(int) ((buf[i]))] & (unsigned short int
) _ISxdigit)
; i += 2, j++) { /*j<additionalInputLen*/
4223 hex_to_byteval(&buf[i], &additionalInput[j]);
4224 }
4225 }
4226 command = RESEED;
4227 fputs(buf, rngresp);
4228 continue;
4229 }
4230
4231 /* Entropy input = ... */
4232 if (strncmp(buf, "EntropyInput", 12) == 0) {
4233 i = 12;
4234 while (isspace(buf[i])((*__ctype_b_loc ())[(int) ((buf[i]))] & (unsigned short int
) _ISspace)
|| buf[i] == '=') {
4235 i++;
4236 }
4237 for (j = 0; isxdigit(buf[i])((*__ctype_b_loc ())[(int) ((buf[i]))] & (unsigned short int
) _ISxdigit)
; i += 2, j++) { /*j<entropyInputLen*/
4238 hex_to_byteval(&buf[i], &entropyInput[j]);
4239 }
4240 fputs(buf, rngresp);
4241 continue;
4242 }
4243
4244 /* nouce = ... */
4245 if (strncmp(buf, "Nonce", 5) == 0) {
4246 i = 5;
4247 while (isspace(buf[i])((*__ctype_b_loc ())[(int) ((buf[i]))] & (unsigned short int
) _ISspace)
|| buf[i] == '=') {
4248 i++;
4249 }
4250 for (j = 0; isxdigit(buf[i])((*__ctype_b_loc ())[(int) ((buf[i]))] & (unsigned short int
) _ISxdigit)
; i += 2, j++) { /*j<nonceLen*/
4251 hex_to_byteval(&buf[i], &nonce[j]);
4252 }
4253 fputs(buf, rngresp);
4254 continue;
4255 }
4256
4257 /* Personalization string = ... */
4258 if (strncmp(buf, "PersonalizationString", 21) == 0) {
4259 if (personalizationString) {
4260 i = 21;
4261 while (isspace(buf[i])((*__ctype_b_loc ())[(int) ((buf[i]))] & (unsigned short int
) _ISspace)
|| buf[i] == '=') {
4262 i++;
4263 }
4264 for (j = 0; isxdigit(buf[i])((*__ctype_b_loc ())[(int) ((buf[i]))] & (unsigned short int
) _ISxdigit)
; i += 2, j++) { /*j<personalizationStringLen*/
4265 hex_to_byteval(&buf[i], &personalizationString[j]);
4266 }
4267 }
4268 fputs(buf, rngresp);
4269 command = INSTANTIATE;
4270 continue;
4271 }
4272
4273 /* Additional input = ... */
4274 if (strncmp(buf, "AdditionalInput", 15) == 0) {
4275 if (additionalInput) {
4276 i = 15;
4277 while (isspace(buf[i])((*__ctype_b_loc ())[(int) ((buf[i]))] & (unsigned short int
) _ISspace)
|| buf[i] == '=') {
4278 i++;
4279 }
4280 for (j = 0; isxdigit(buf[i])((*__ctype_b_loc ())[(int) ((buf[i]))] & (unsigned short int
) _ISxdigit)
; i += 2, j++) { /*j<additionalInputLen*/
4281 hex_to_byteval(&buf[i], &additionalInput[j]);
4282 }
4283 }
4284 if (genResult) {
4285 command = RESULT;
4286 } else {
4287 command = GENERATE;
4288 genResult = PR_TRUE1; /* next time generate result */
4289 }
4290 fputs(buf, rngresp);
4291 continue;
4292 }
4293
4294 /* Returned bits = ... */
4295 if (strncmp(buf, "ReturnedBits", 12) == 0) {
4296 i = 12;
4297 while (isspace(buf[i])((*__ctype_b_loc ())[(int) ((buf[i]))] & (unsigned short int
) _ISspace)
|| buf[i] == '=') {
4298 i++;
4299 }
4300 for (j = 0; isxdigit(buf[i])((*__ctype_b_loc ())[(int) ((buf[i]))] & (unsigned short int
) _ISxdigit)
; i += 2, j++) { /*j<additionalInputLen*/
4301 hex_to_byteval(&buf[i], &predictedreturn_bytes[j]);
4302 }
4303
4304 if (memcmp(return_bytes,
4305 predictedreturn_bytes, return_bytes_len) != 0) {
4306 if (debug) {
4307 fprintf(rngresp, "# Generate failed:\n");
4308 fputs("# predicted=", rngresp);
4309 to_hex_str(buf, predictedreturn_bytes,
4310 return_bytes_len);
4311 fputs(buf, rngresp);
4312 fputs("\n# actual = ", rngresp);
4313 fputs(buf2, rngresp);
4314 fputc('\n', rngresp);
4315
4316 } else {
4317 fprintf(stderrstderr, "Generate failed:\n");
4318 fputs(" predicted=", stderrstderr);
4319 to_hex_str(buf, predictedreturn_bytes,
4320 return_bytes_len);
4321 fputs(buf, stderrstderr);
4322 fputs("\n actual = ", stderrstderr);
4323 fputs(buf2, stderrstderr);
4324 fputc('\n', stderrstderr);
4325 }
4326 }
4327 memset(predictedreturn_bytes, 0, return_bytes_len);
4328
4329 continue;
4330 }
4331 }
4332loser:
4333 if (predictedreturn_bytes) {
4334 PORT_FreePORT_Free_Util(predictedreturn_bytes);
4335 }
4336 if (return_bytes) {
4337 PORT_FreePORT_Free_Util(return_bytes);
4338 }
4339 if (additionalInput) {
4340 PORT_FreePORT_Free_Util(additionalInput);
4341 }
4342 if (personalizationString) {
4343 PORT_FreePORT_Free_Util(personalizationString);
4344 }
4345 if (nonce) {
4346 PORT_FreePORT_Free_Util(nonce);
4347 }
4348 if (entropyInput) {
4349 PORT_FreePORT_Free_Util(entropyInput);
4350 }
4351 fclose(rngreq);
4352}
4353
4354/*
4355 * Perform the RNG Variable Seed Test (VST) for the RNG algorithm
4356 * "DSA - Generation of X", used both as specified and as a generic
4357 * purpose RNG. The presence of "Q = ..." in the REQUEST file
4358 * indicates we are using the algorithm as specified.
4359 *
4360 * reqfn is the pathname of the REQUEST file.
4361 *
4362 * The output RESPONSE file is written to stdout.
4363 */
4364void
4365rng_vst(char *reqfn)
4366{
4367 char buf[256]; /* holds one line from the input REQUEST file.
4368 * needs to be large enough to hold the longest
4369 * line "XSeed = <128 hex digits>\n".
4370 */
4371 FILE *rngreq; /* input stream from the REQUEST file */
4372 FILE *rngresp; /* output stream to the RESPONSE file */
4373 unsigned int i, j;
4374 unsigned char Q[DSA1_SUBPRIME_LEN20];
4375 PRBool hasQ = PR_FALSE0;
4376 unsigned int b = 0; /* 160 <= b <= 512, b is a multiple of 8 */
4377 unsigned char XKey[512 / 8];
4378 unsigned char XSeed[512 / 8];
4379 unsigned char GENX[DSA1_SIGNATURE_LEN(20 * 2)];
4380 unsigned char DSAX[DSA1_SUBPRIME_LEN20];
4381 SECStatus rv;
4382
4383 rngreq = fopen(reqfn, "r");
4384 rngresp = stdoutstdout;
4385 while (fgets(buf, sizeof buf, rngreq) != NULL((void*)0)) {
4386 /* a comment or blank line */
4387 if (buf[0] == '#' || buf[0] == '\n') {
4388 fputs(buf, rngresp);
4389 continue;
4390 }
4391 /* [Xchange - SHA1] */
4392 if (buf[0] == '[') {
4393 fputs(buf, rngresp);
4394 continue;
4395 }
4396 /* Q = ... */
4397 if (buf[0] == 'Q') {
4398 i = 1;
4399 while (isspace(buf[i])((*__ctype_b_loc ())[(int) ((buf[i]))] & (unsigned short int
) _ISspace)
|| buf[i] == '=') {
4400 i++;
4401 }
4402 for (j = 0; j < sizeof Q; i += 2, j++) {
4403 hex_to_byteval(&buf[i], &Q[j]);
4404 }
4405 fputs(buf, rngresp);
4406 hasQ = PR_TRUE1;
4407 continue;
4408 }
4409 /* "COUNT = x" begins a new data set */
4410 if (strncmp(buf, "COUNT", 5) == 0) {
4411 /* zeroize the variables for the test with this data set */
4412 b = 0;
4413 memset(XKey, 0, sizeof XKey);
4414 memset(XSeed, 0, sizeof XSeed);
4415 fputs(buf, rngresp);
4416 continue;
4417 }
4418 /* b = ... */
4419 if (buf[0] == 'b') {
4420 i = 1;
4421 while (isspace(buf[i])((*__ctype_b_loc ())[(int) ((buf[i]))] & (unsigned short int
) _ISspace)
|| buf[i] == '=') {
4422 i++;
4423 }
4424 b = atoi(&buf[i]);
4425 if (b < 160 || b > 512 || b % 8 != 0) {
4426 goto loser;
4427 }
4428 fputs(buf, rngresp);
4429 continue;
4430 }
4431 /* XKey = ... */
4432 if (strncmp(buf, "XKey", 4) == 0) {
4433 i = 4;
4434 while (isspace(buf[i])((*__ctype_b_loc ())[(int) ((buf[i]))] & (unsigned short int
) _ISspace)
|| buf[i] == '=') {
4435 i++;
4436 }
4437 for (j = 0; j < b / 8; i += 2, j++) {
4438 hex_to_byteval(&buf[i], &XKey[j]);
4439 }
4440 fputs(buf, rngresp);
4441 continue;
4442 }
4443 /* XSeed = ... */
4444 if (strncmp(buf, "XSeed", 5) == 0) {
4445 i = 5;
4446 while (isspace(buf[i])((*__ctype_b_loc ())[(int) ((buf[i]))] & (unsigned short int
) _ISspace)
|| buf[i] == '=') {
4447 i++;
4448 }
4449 for (j = 0; j < b / 8; i += 2, j++) {
4450 hex_to_byteval(&buf[i], &XSeed[j]);
4451 }
4452 fputs(buf, rngresp);
4453
4454 rv = FIPS186Change_GenerateX(XKey, XSeed, GENX);
4455 if (rv != SECSuccess) {
4456 goto loser;
4457 }
4458 fputs("X = ", rngresp);
4459 if (hasQ) {
4460 rv = FIPS186Change_ReduceModQForDSA(GENX, Q, DSAX);
4461 if (rv != SECSuccess) {
4462 goto loser;
4463 }
4464 to_hex_str(buf, DSAX, sizeof DSAX);
4465 } else {
4466 to_hex_str(buf, GENX, sizeof GENX);
4467 }
4468 fputs(buf, rngresp);
4469 fputc('\n', rngresp);
4470 continue;
4471 }
4472 }
4473loser:
4474 fclose(rngreq);
4475}
4476
4477/*
4478 * Perform the RNG Monte Carlo Test (MCT) for the RNG algorithm
4479 * "DSA - Generation of X", used both as specified and as a generic
4480 * purpose RNG. The presence of "Q = ..." in the REQUEST file
4481 * indicates we are using the algorithm as specified.
4482 *
4483 * reqfn is the pathname of the REQUEST file.
4484 *
4485 * The output RESPONSE file is written to stdout.
4486 */
4487void
4488rng_mct(char *reqfn)
4489{
4490 char buf[256]; /* holds one line from the input REQUEST file.
4491 * needs to be large enough to hold the longest
4492 * line "XSeed = <128 hex digits>\n".
4493 */
4494 FILE *rngreq; /* input stream from the REQUEST file */
4495 FILE *rngresp; /* output stream to the RESPONSE file */
4496 unsigned int i, j;
4497 unsigned char Q[DSA1_SUBPRIME_LEN20];
4498 PRBool hasQ = PR_FALSE0;
4499 unsigned int b = 0; /* 160 <= b <= 512, b is a multiple of 8 */
4500 unsigned char XKey[512 / 8];
4501 unsigned char XSeed[512 / 8];
4502 unsigned char GENX[2 * SHA1_LENGTH20];
4503 unsigned char DSAX[DSA1_SUBPRIME_LEN20];
4504 SECStatus rv;
4505
4506 rngreq = fopen(reqfn, "r");
4507 rngresp = stdoutstdout;
4508 while (fgets(buf, sizeof buf, rngreq) != NULL((void*)0)) {
4509 /* a comment or blank line */
4510 if (buf[0] == '#' || buf[0] == '\n') {
4511 fputs(buf, rngresp);
4512 continue;
4513 }
4514 /* [Xchange - SHA1] */
4515 if (buf[0] == '[') {
4516 fputs(buf, rngresp);
4517 continue;
4518 }
4519 /* Q = ... */
4520 if (buf[0] == 'Q') {
4521 i = 1;
4522 while (isspace(buf[i])((*__ctype_b_loc ())[(int) ((buf[i]))] & (unsigned short int
) _ISspace)
|| buf[i] == '=') {
4523 i++;
4524 }
4525 for (j = 0; j < sizeof Q; i += 2, j++) {
4526 hex_to_byteval(&buf[i], &Q[j]);
4527 }
4528 fputs(buf, rngresp);
4529 hasQ = PR_TRUE1;
4530 continue;
4531 }
4532 /* "COUNT = x" begins a new data set */
4533 if (strncmp(buf, "COUNT", 5) == 0) {
4534 /* zeroize the variables for the test with this data set */
4535 b = 0;
4536 memset(XKey, 0, sizeof XKey);
4537 memset(XSeed, 0, sizeof XSeed);
4538 fputs(buf, rngresp);
4539 continue;
4540 }
4541 /* b = ... */
4542 if (buf[0] == 'b') {
4543 i = 1;
4544 while (isspace(buf[i])((*__ctype_b_loc ())[(int) ((buf[i]))] & (unsigned short int
) _ISspace)
|| buf[i] == '=') {
4545 i++;
4546 }
4547 b = atoi(&buf[i]);
4548 if (b < 160 || b > 512 || b % 8 != 0) {
4549 goto loser;
4550 }
4551 fputs(buf, rngresp);
4552 continue;
4553 }
4554 /* XKey = ... */
4555 if (strncmp(buf, "XKey", 4) == 0) {
4556 i = 4;
4557 while (isspace(buf[i])((*__ctype_b_loc ())[(int) ((buf[i]))] & (unsigned short int
) _ISspace)
|| buf[i] == '=') {
4558 i++;
4559 }
4560 for (j = 0; j < b / 8; i += 2, j++) {
4561 hex_to_byteval(&buf[i], &XKey[j]);
4562 }
4563 fputs(buf, rngresp);
4564 continue;
4565 }
4566 /* XSeed = ... */
4567 if (strncmp(buf, "XSeed", 5) == 0) {
4568 unsigned int k;
4569 i = 5;
4570 while (isspace(buf[i])((*__ctype_b_loc ())[(int) ((buf[i]))] & (unsigned short int
) _ISspace)
|| buf[i] == '=') {
4571 i++;
4572 }
4573 for (j = 0; j < b / 8; i += 2, j++) {
4574 hex_to_byteval(&buf[i], &XSeed[j]);
4575 }
4576 fputs(buf, rngresp);
4577
4578 for (k = 0; k < 10000; k++) {
4579 rv = FIPS186Change_GenerateX(XKey, XSeed, GENX);
4580 if (rv != SECSuccess) {
4581 goto loser;
4582 }
4583 }
4584 fputs("X = ", rngresp);
4585 if (hasQ) {
4586 rv = FIPS186Change_ReduceModQForDSA(GENX, Q, DSAX);
4587 if (rv != SECSuccess) {
4588 goto loser;
4589 }
4590 to_hex_str(buf, DSAX, sizeof DSAX);
4591 } else {
4592 to_hex_str(buf, GENX, sizeof GENX);
4593 }
4594 fputs(buf, rngresp);
4595 fputc('\n', rngresp);
4596 continue;
4597 }
4598 }
4599loser:
4600 fclose(rngreq);
4601}
4602
4603/*
4604 * Calculate the SHA Message Digest
4605 *
4606 * MD = Message digest
4607 * MDLen = length of Message Digest and SHA_Type
4608 * msg = message to digest
4609 * msgLen = length of message to digest
4610 */
4611SECStatus
4612sha_calcMD(unsigned char *MD, unsigned int MDLen, unsigned char *msg, unsigned int msgLen)
4613{
4614 HASH_HashType hashType = sha_get_hashType(MDLen * PR_BITS_PER_BYTE8);
4615
4616 return fips_hashBuf(hashType, MD, msg, msgLen);
4617}
4618
4619/*
4620 * Perform the SHA Monte Carlo Test
4621 *
4622 * MDLen = length of Message Digest and SHA_Type
4623 * seed = input seed value
4624 * resp = is the output response file.
4625 */
4626SECStatus
4627sha_mct_test(unsigned int MDLen, unsigned char *seed, FILE *resp)
4628{
4629 int i, j;
4630 unsigned int msgLen = MDLen * 3;
4631 unsigned char MD_i3[HASH_LENGTH_MAX64]; /* MD[i-3] */
4632 unsigned char MD_i2[HASH_LENGTH_MAX64]; /* MD[i-2] */
4633 unsigned char MD_i1[HASH_LENGTH_MAX64]; /* MD[i-1] */
4634 unsigned char MD_i[HASH_LENGTH_MAX64]; /* MD[i] */
4635 unsigned char msg[HASH_LENGTH_MAX64 * 3];
4636 char buf[HASH_LENGTH_MAX64 * 2 + 1]; /* MAX buf MD_i as a hex string */
4637
4638 for (j = 0; j < 100; j++) {
4639 /* MD_0 = MD_1 = MD_2 = seed */
4640 memcpy(MD_i3, seed, MDLen);
4641 memcpy(MD_i2, seed, MDLen);
4642 memcpy(MD_i1, seed, MDLen);
4643
4644 for (i = 3; i < 1003; i++) {
4645 /* Mi = MD[i-3] || MD [i-2] || MD [i-1] */
4646 memcpy(msg, MD_i3, MDLen);
4647 memcpy(&msg[MDLen], MD_i2, MDLen);
4648 memcpy(&msg[MDLen * 2], MD_i1, MDLen);
4649
4650 /* MDi = SHA(Msg) */
4651 if (sha_calcMD(MD_i, MDLen,
4652 msg, msgLen) != SECSuccess) {
4653 return SECFailure;
4654 }
4655
4656 /* save MD[i-3] MD[i-2] MD[i-1] */
4657 memcpy(MD_i3, MD_i2, MDLen);
4658 memcpy(MD_i2, MD_i1, MDLen);
4659 memcpy(MD_i1, MD_i, MDLen);
4660 }
4661
4662 /* seed = MD_i */
4663 memcpy(seed, MD_i, MDLen);
4664
4665 snprintf(buf, sizeof(buf), "COUNT = %d\n", j);
4666 fputs(buf, resp);
4667
4668 /* output MD_i */
4669 fputs("MD = ", resp);
4670 to_hex_str(buf, MD_i, MDLen);
4671 fputs(buf, resp);
4672 fputc('\n', resp);
4673 }
4674
4675 return SECSuccess;
4676}
4677
4678/*
4679 * Perform the SHA Tests.
4680 *
4681 * reqfn is the pathname of the input REQUEST file.
4682 *
4683 * The output RESPONSE file is written to stdout.
4684 */
4685void
4686sha_test(char *reqfn)
4687{
4688 unsigned int i, j;
4689 unsigned int MDlen = 0; /* the length of the Message Digest in Bytes */
4690 unsigned int msgLen = 0; /* the length of the input Message in Bytes */
4691 unsigned char *msg = NULL((void*)0); /* holds the message to digest.*/
4692 size_t bufSize = 256 * 128; /*MAX buffer size */
4693 char *buf = NULL((void*)0); /* holds one line from the input REQUEST file.*/
4694 unsigned char seed[HASH_LENGTH_MAX64]; /* max size of seed 64 bytes */
4695 unsigned char MD[HASH_LENGTH_MAX64]; /* message digest */
4696
4697 FILE *req = NULL((void*)0); /* input stream from the REQUEST file */
4698 FILE *resp; /* output stream to the RESPONSE file */
4699
4700 buf = PORT_ZAllocPORT_ZAlloc_Util(bufSize);
4701 if (buf == NULL((void*)0)) {
4702 goto loser;
4703 }
4704
4705 /* zeroize the variables for the test with this data set */
4706 memset(seed, 0, sizeof seed);
4707
4708 req = fopen(reqfn, "r");
4709 resp = stdoutstdout;
4710 while (fgets(buf, bufSize, req) != NULL((void*)0)) {
4711
4712 /* a comment or blank line */
4713 if (buf[0] == '#' || buf[0] == '\n') {
4714 fputs(buf, resp);
4715 continue;
4716 }
4717 /* [L = Length of the Message Digest and sha_type */
4718 if (buf[0] == '[') {
4719 if (strncmp(&buf[1], "L ", 1) == 0) {
4720 i = 2;
4721 while (isspace(buf[i])((*__ctype_b_loc ())[(int) ((buf[i]))] & (unsigned short int
) _ISspace)
|| buf[i] == '=') {
4722 i++;
4723 }
4724 MDlen = atoi(&buf[i]);
4725 fputs(buf, resp);
4726 continue;
4727 }
4728 }
4729 /* Len = Length of the Input Message Length ... */
4730 if (strncmp(buf, "Len", 3) == 0) {
4731 i = 3;
4732 while (isspace(buf[i])((*__ctype_b_loc ())[(int) ((buf[i]))] & (unsigned short int
) _ISspace)
|| buf[i] == '=') {
4733 i++;
4734 }
4735 if (msg) {
4736 PORT_ZFreePORT_ZFree_Util(msg, msgLen);
4737 msg = NULL((void*)0);
4738 }
4739 msgLen = atoi(&buf[i]); /* in bits */
4740 if (msgLen % 8 != 0) {
4741 fprintf(stderrstderr, "SHA tests are incorrectly configured for "
4742 "BIT oriented implementations\n");
4743 goto loser;
4744 }
4745 msgLen = msgLen / 8; /* convert to bytes */
4746 fputs(buf, resp);
4747 msg = PORT_ZAllocPORT_ZAlloc_Util(msgLen);
4748 if (msg == NULL((void*)0) && msgLen != 0) {
4749 goto loser;
4750 }
4751 continue;
4752 }
4753 /* MSG = ... */
4754 if (strncmp(buf, "Msg", 3) == 0) {
4755 i = 3;
4756 while (isspace(buf[i])((*__ctype_b_loc ())[(int) ((buf[i]))] & (unsigned short int
) _ISspace)
|| buf[i] == '=') {
4757 i++;
4758 }
4759 for (j = 0; j < msgLen; i += 2, j++) {
4760 hex_to_byteval(&buf[i], &msg[j]);
4761 }
4762 fputs(buf, resp);
4763 /* calculate the Message Digest */
4764 memset(MD, 0, sizeof MD);
4765 if (sha_calcMD(MD, MDlen,
4766 msg, msgLen) != SECSuccess) {
4767 goto loser;
4768 }
4769
4770 fputs("MD = ", resp);
4771 to_hex_str(buf, MD, MDlen);
4772 fputs(buf, resp);
4773 fputc('\n', resp);
4774
4775 continue;
4776 }
4777 /* Seed = ... */
4778 if (strncmp(buf, "Seed", 4) == 0) {
4779 i = 4;
4780 while (isspace(buf[i])((*__ctype_b_loc ())[(int) ((buf[i]))] & (unsigned short int
) _ISspace)
|| buf[i] == '=') {
4781 i++;
4782 }
4783 for (j = 0; j < sizeof seed; i += 2, j++) {
4784 hex_to_byteval(&buf[i], &seed[j]);
4785 }
4786
4787 fputs(buf, resp);
4788 fputc('\n', resp);
4789
4790 /* do the Monte Carlo test */
4791 if (sha_mct_test(MDlen, seed, resp) != SECSuccess) {
4792 goto loser;
4793 }
4794
4795 continue;
4796 }
4797 }
4798loser:
4799 if (req) {
4800 fclose(req);
4801 }
4802 if (buf) {
4803 PORT_ZFreePORT_ZFree_Util(buf, bufSize);
4804 }
4805 if (msg) {
4806 PORT_ZFreePORT_ZFree_Util(msg, msgLen);
4807 }
4808}
4809
4810/****************************************************/
4811/* HMAC SHA-X calc */
4812/* hmac_computed - the computed HMAC */
4813/* hmac_length - the length of the computed HMAC */
4814/* secret_key - secret key to HMAC */
4815/* secret_key_length - length of secret key, */
4816/* message - message to HMAC */
4817/* message_length - length ofthe message */
4818/****************************************************/
4819static SECStatus
4820hmac_calc(unsigned char *hmac_computed,
4821 const unsigned int hmac_length,
4822 const unsigned char *secret_key,
4823 const unsigned int secret_key_length,
4824 const unsigned char *message,
4825 const unsigned int message_length,
4826 const HASH_HashType hashAlg)
4827{
4828 SECStatus hmac_status = SECFailure;
4829 HMACContext *cx = NULL((void*)0);
4830 SECHashObject *hashObj = NULL((void*)0);
4831 unsigned int bytes_hashed = 0;
4832
4833 hashObj = (SECHashObject *)HASH_GetRawHashObject(hashAlg);
4834
4835 if (!hashObj)
4836 return (SECFailure);
4837
4838 cx = HMAC_Create(hashObj, secret_key,
4839 secret_key_length,
4840 PR_TRUE1); /* PR_TRUE for in FIPS mode */
4841
4842 if (cx == NULL((void*)0))
4843 return (SECFailure);
4844
4845 HMAC_Begin(cx);
4846 HMAC_Update(cx, message, message_length);
4847 hmac_status = HMAC_Finish(cx, hmac_computed, &bytes_hashed,
4848 hmac_length);
4849
4850 HMAC_Destroy(cx, PR_TRUE1);
4851
4852 return (hmac_status);
4853}
4854
4855/*
4856 * Perform the HMAC Tests.
4857 *
4858 * reqfn is the pathname of the input REQUEST file.
4859 *
4860 * The output RESPONSE file is written to stdout.
4861 */
4862void
4863hmac_test(char *reqfn)
4864{
4865 unsigned int i, j;
4866 size_t bufSize = 400; /* MAX buffer size */
4867 char *buf = NULL((void*)0); /* holds one line from the input REQUEST file.*/
4868 unsigned int keyLen = 0; /* Key Length */
4869 unsigned char key[200]; /* key MAX size = 184 */
4870 unsigned int msgLen = 128; /* the length of the input */
4871 /* Message is always 128 Bytes */
4872 unsigned char *msg = NULL((void*)0); /* holds the message to digest.*/
4873 unsigned int HMACLen = 0; /* the length of the HMAC Bytes */
4874 unsigned int TLen = 0; /* the length of the requested */
4875 /* truncated HMAC Bytes */
4876 unsigned char HMAC[HASH_LENGTH_MAX64]; /* computed HMAC */
4877 unsigned char expectedHMAC[HASH_LENGTH_MAX64]; /* for .fax files that have */
4878 /* supplied known answer */
4879 HASH_HashType hash_alg = HASH_AlgNULL; /* HMAC type */
4880
4881 FILE *req = NULL((void*)0); /* input stream from the REQUEST file */
4882 FILE *resp; /* output stream to the RESPONSE file */
4883
4884 buf = PORT_ZAllocPORT_ZAlloc_Util(bufSize);
4885 if (buf == NULL((void*)0)) {
4886 goto loser;
4887 }
4888 msg = PORT_ZAllocPORT_ZAlloc_Util(msgLen);
4889 if (msg == NULL((void*)0)) {
4890 goto loser;
4891 }
4892
4893 req = fopen(reqfn, "r");
4894 resp = stdoutstdout;
4895 while (fgets(buf, bufSize, req) != NULL((void*)0)) {
4896 if (strncmp(buf, "Mac", 3) == 0) {
4897 i = 3;
4898 while (isspace(buf[i])((*__ctype_b_loc ())[(int) ((buf[i]))] & (unsigned short int
) _ISspace)
|| buf[i] == '=') {
4899 i++;
4900 }
4901 memset(expectedHMAC, 0, HASH_LENGTH_MAX64);
4902 for (j = 0; isxdigit(buf[i])((*__ctype_b_loc ())[(int) ((buf[i]))] & (unsigned short int
) _ISxdigit)
; i += 2, j++) {
4903 hex_to_byteval(&buf[i], &expectedHMAC[j]);
4904 }
4905 if (memcmp(HMAC, expectedHMAC, TLen) != 0) {
4906 fprintf(stderrstderr, "Generate failed:\n");
4907 fputs(" expected=", stderrstderr);
4908 to_hex_str(buf, expectedHMAC,
4909 TLen);
4910 fputs(buf, stderrstderr);
4911 fputs("\n generated=", stderrstderr);
4912 to_hex_str(buf, HMAC,
4913 TLen);
4914 fputs(buf, stderrstderr);
4915 fputc('\n', stderrstderr);
4916 }
4917 }
4918
4919 /* a comment or blank line */
4920 if (buf[0] == '#' || buf[0] == '\n') {
4921 fputs(buf, resp);
4922 continue;
4923 }
4924 /* [L = Length of the MAC and HASH_type */
4925 if (buf[0] == '[') {
4926 if (strncmp(&buf[1], "L ", 1) == 0) {
4927 i = 2;
4928 while (isspace(buf[i])((*__ctype_b_loc ())[(int) ((buf[i]))] & (unsigned short int
) _ISspace)
|| buf[i] == '=') {
4929 i++;
4930 }
4931 /* HMACLen will get reused for Tlen */
4932 HMACLen = atoi(&buf[i]);
4933 hash_alg = sha_get_hashType(HMACLen * PR_BITS_PER_BYTE8);
4934 if (hash_alg == HASH_AlgNULL) {
4935 goto loser;
4936 }
4937 fputs(buf, resp);
4938 continue;
4939 }
4940 }
4941 /* Count = test iteration number*/
4942 if (strncmp(buf, "Count ", 5) == 0) {
4943 /* count can just be put into resp file */
4944 fputs(buf, resp);
4945 /* zeroize the variables for the test with this data set */
4946 keyLen = 0;
4947 TLen = 0;
4948 memset(key, 0, sizeof key);
4949 memset(msg, 0, msgLen);
4950 memset(HMAC, 0, sizeof HMAC);
4951 continue;
4952 }
4953 /* KLen = Length of the Input Secret Key ... */
4954 if (strncmp(buf, "Klen", 4) == 0) {
4955 i = 4;
4956 while (isspace(buf[i])((*__ctype_b_loc ())[(int) ((buf[i]))] & (unsigned short int
) _ISspace)
|| buf[i] == '=') {
4957 i++;
4958 }
4959 keyLen = atoi(&buf[i]); /* in bytes */
4960 fputs(buf, resp);
4961 continue;
4962 }
4963 /* key = the secret key for the key to MAC */
4964 if (strncmp(buf, "Key", 3) == 0) {
4965 i = 3;
4966 while (isspace(buf[i])((*__ctype_b_loc ())[(int) ((buf[i]))] & (unsigned short int
) _ISspace)
|| buf[i] == '=') {
4967 i++;
4968 }
4969 for (j = 0; j < keyLen; i += 2, j++) {
4970 hex_to_byteval(&buf[i], &key[j]);
4971 }
4972 fputs(buf, resp);
4973 }
4974 /* TLen = Length of the calculated HMAC */
4975 if (strncmp(buf, "Tlen", 4) == 0) {
4976 i = 4;
4977 while (isspace(buf[i])((*__ctype_b_loc ())[(int) ((buf[i]))] & (unsigned short int
) _ISspace)
|| buf[i] == '=') {
4978 i++;
4979 }
4980 TLen = atoi(&buf[i]); /* in bytes */
4981 fputs(buf, resp);
4982 continue;
4983 }
4984 /* MSG = to HMAC always 128 bytes for these tests */
4985 if (strncmp(buf, "Msg", 3) == 0) {
4986 i = 3;
4987 while (isspace(buf[i])((*__ctype_b_loc ())[(int) ((buf[i]))] & (unsigned short int
) _ISspace)
|| buf[i] == '=') {
4988 i++;
4989 }
4990 for (j = 0; j < msgLen; i += 2, j++) {
4991 hex_to_byteval(&buf[i], &msg[j]);
4992 }
4993 fputs(buf, resp);
4994 /* calculate the HMAC and output */
4995 if (hmac_calc(HMAC, HMACLen, key, keyLen,
4996 msg, msgLen, hash_alg) != SECSuccess) {
4997 goto loser;
4998 }
4999 fputs("Mac = ", resp);
5000 to_hex_str(buf, HMAC, TLen);
5001 fputs(buf, resp);
5002 fputc('\n', resp);
5003 continue;
5004 }
5005 }
5006loser:
5007 if (req) {
5008 fclose(req);
5009 }
5010 if (buf) {
5011 PORT_ZFreePORT_ZFree_Util(buf, bufSize);
5012 }
5013 if (msg) {
5014 PORT_ZFreePORT_ZFree_Util(msg, msgLen);
5015 }
5016}
5017
5018/*
5019 * Perform the DSA Key Pair Generation Test.
5020 *
5021 * reqfn is the pathname of the REQUEST file.
5022 *
5023 * The output RESPONSE file is written to stdout.
5024 */
5025void
5026dsa_keypair_test(char *reqfn)
5027{
5028 char buf[800]; /* holds one line from the input REQUEST file
5029 * or to the output RESPONSE file.
5030 * 800 to hold (384 public key (x2 for HEX) + 1'\n'
5031 */
5032 FILE *dsareq; /* input stream from the REQUEST file */
5033 FILE *dsaresp; /* output stream to the RESPONSE file */
5034 int count;
5035 int N;
5036 int L;
5037 int i;
5038 PQGParams *pqg = NULL((void*)0);
5039 PQGVerify *vfy = NULL((void*)0);
5040 PRBool use_dsa1 = PR_FALSE0;
5041 int keySizeIndex; /* index for valid key sizes */
5042
5043 dsareq = fopen(reqfn, "r");
5044 dsaresp = stdoutstdout;
5045 while (fgets(buf, sizeof buf, dsareq) != NULL((void*)0)) {
5046 /* a comment or blank line */
5047 if (buf[0] == '#' || buf[0] == '\n') {
5048 fputs(buf, dsaresp);
5049 continue;
5050 }
5051
5052 /* [Mod = x] */
5053 if (buf[0] == '[') {
5054 if (pqg != NULL((void*)0)) {
5055 PQG_DestroyParams(pqg);
5056 pqg = NULL((void*)0);
5057 }
5058 if (vfy != NULL((void*)0)) {
5059 PQG_DestroyVerify(vfy);
5060 vfy = NULL((void*)0);
5061 }
5062
5063 if (sscanf(buf, "[mod = L=%d, N=%d]", &L, &N) != 2) {
5064 use_dsa1 = PR_TRUE1;
5065 if (sscanf(buf, "[mod = %d]", &L) != 1) {
5066 goto loser;
5067 }
5068 }
5069 fputs(buf, dsaresp);
5070 fputc('\n', dsaresp);
5071
5072 if (use_dsa1) {
5073 /*************************************************************
5074 * PQG_ParamGenSeedLen doesn't take a key size, it takes an
5075 * index that points to a valid key size.
5076 */
5077 keySizeIndex = PQG_PBITS_TO_INDEX(L)(((L) < 512 || (L) > 1024 || (L) % 64) ? -1 : (int)((L)
-512) / 64)
;
5078 if (keySizeIndex == -1 || L < 512 || L > 1024) {
5079 fprintf(dsaresp,
5080 "DSA key size must be a multiple of 64 between 512 "
5081 "and 1024, inclusive");
5082 goto loser;
5083 }
5084
5085 /* Generate the parameters P, Q, and G */
5086 if (PQG_ParamGenSeedLen(keySizeIndex, PQG_TEST_SEED_BYTES20,
5087 &pqg, &vfy) !=
5088 SECSuccess) {
5089 fprintf(dsaresp,
5090 "ERROR: Unable to generate PQG parameters");
5091 goto loser;
5092 }
5093 } else {
5094 if (PQG_ParamGenV2(L, N, N, &pqg, &vfy) != SECSuccess) {
5095 fprintf(dsaresp,
5096 "ERROR: Unable to generate PQG parameters");
5097 goto loser;
5098 }
5099 }
5100
5101 /* output P, Q, and G */
5102 to_hex_str(buf, pqg->prime.data, pqg->prime.len);
5103 fprintf(dsaresp, "P = %s\n", buf);
5104 to_hex_str(buf, pqg->subPrime.data, pqg->subPrime.len);
5105 fprintf(dsaresp, "Q = %s\n", buf);
5106 to_hex_str(buf, pqg->base.data, pqg->base.len);
5107 fprintf(dsaresp, "G = %s\n\n", buf);
5108 continue;
5109 }
5110 /* N = ...*/
5111 if (buf[0] == 'N') {
5112
5113 if (sscanf(buf, "N = %d", &count) != 1) {
5114 goto loser;
5115 }
5116 /* Generate a DSA key, and output the key pair for N times */
5117 for (i = 0; i < count; i++) {
5118 DSAPrivateKey *dsakey = NULL((void*)0);
5119 if (DSA_NewKey(pqg, &dsakey) != SECSuccess) {
5120 fprintf(dsaresp, "ERROR: Unable to generate DSA key");
5121 goto loser;
5122 }
5123 to_hex_str(buf, dsakey->privateValue.data,
5124 dsakey->privateValue.len);
5125 fprintf(dsaresp, "X = %s\n", buf);
5126 to_hex_str(buf, dsakey->publicValue.data,
5127 dsakey->publicValue.len);
5128 fprintf(dsaresp, "Y = %s\n\n", buf);
5129 PORT_FreeArenaPORT_FreeArena_Util(dsakey->params.arena, PR_TRUE1);
5130 dsakey = NULL((void*)0);
5131 }
5132 continue;
5133 }
5134 }
5135loser:
5136 fclose(dsareq);
5137}
5138
5139/*
5140 * pqg generation type
5141 */
5142typedef enum {
5143 FIPS186_1, /* Generate/Verify P,Q & G according to FIPS 186-1 */
5144 A_1_2_1, /* Generate Provable P & Q */
5145 A_1_1_3, /* Verify Probable P & Q */
5146 A_1_2_2, /* Verify Provable P & Q */
5147 A_2_1, /* Generate Unverifiable G */
5148 A_2_2, /* Assure Unverifiable G */
5149 A_2_3, /* Generate Verifiable G */
5150 A_2_4 /* Verify Verifiable G */
5151} dsa_pqg_type;
5152
5153/*
5154 * Perform the DSA Domain Parameter Validation Test.
5155 *
5156 * reqfn is the pathname of the REQUEST file.
5157 *
5158 * The output RESPONSE file is written to stdout.
5159 */
5160void
5161dsa_pqgver_test(char *reqfn)
5162{
5163 char buf[800]; /* holds one line from the input REQUEST file
5164 * or to the output RESPONSE file.
5165 * 800 to hold (384 public key (x2 for HEX) + P = ...
5166 */
5167 FILE *dsareq; /* input stream from the REQUEST file */
5168 FILE *dsaresp; /* output stream to the RESPONSE file */
5169 int N;
5170 int L;
5171 unsigned int i, j;
5172 PQGParams pqg;
5173 PQGVerify vfy;
5174 unsigned int pghSize = 0; /* size for p, g, and h */
5175 dsa_pqg_type type = FIPS186_1;
5176
5177 dsareq = fopen(reqfn, "r");
5178 dsaresp = stdoutstdout;
5179 memset(&pqg, 0, sizeof(pqg));
5180 memset(&vfy, 0, sizeof(vfy));
5181
5182 while (fgets(buf, sizeof buf, dsareq) != NULL((void*)0)) {
5183 /* a comment or blank line */
5184 if (buf[0] == '#' || buf[0] == '\n') {
5185 fputs(buf, dsaresp);
5186 continue;
5187 }
5188
5189 /* [A.xxxxx ] */
5190 if (buf[0] == '[' && buf[1] == 'A') {
5191
5192 if (strncmp(&buf[1], "A.1.1.3", 7) == 0) {
5193 type = A_1_1_3;
5194 } else if (strncmp(&buf[1], "A.2.2", 5) == 0) {
5195 type = A_2_2;
5196 } else if (strncmp(&buf[1], "A.2.4", 5) == 0) {
5197 type = A_2_4;
5198 } else if (strncmp(&buf[1], "A.1.2.2", 7) == 0) {
5199 type = A_1_2_2;
5200 /* validate our output from PQGGEN */
5201 } else if (strncmp(&buf[1], "A.1.1.2", 7) == 0) {
5202 type = A_2_4; /* validate PQ and G together */
5203 } else {
5204 fprintf(stderrstderr, "Unknown dsa ver test %s\n", &buf[1]);
5205 exit(1);
5206 }
5207
5208 fputs(buf, dsaresp);
5209 continue;
5210 }
5211
5212 /* [Mod = x] */
5213 if (buf[0] == '[') {
5214
5215 if (type == FIPS186_1) {
5216 N = 160;
5217 if (sscanf(buf, "[mod = %d]", &L) != 1) {
5218 goto loser;
5219 }
5220 } else if (sscanf(buf, "[mod = L=%d, N=%d", &L, &N) != 2) {
5221 goto loser;
5222 }
5223
5224 if (pqg.prime.data) { /* P */
5225 SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(&pqg.prime, PR_FALSE0);
5226 }
5227 if (pqg.subPrime.data) { /* Q */
5228 SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(&pqg.subPrime, PR_FALSE0);
5229 }
5230 if (pqg.base.data) { /* G */
5231 SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(&pqg.base, PR_FALSE0);
5232 }
5233 if (vfy.seed.data) { /* seed */
5234 SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(&vfy.seed, PR_FALSE0);
5235 }
5236 if (vfy.h.data) { /* H */
5237 SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(&vfy.h, PR_FALSE0);
5238 }
5239
5240 fputs(buf, dsaresp);
5241
5242 /*calculate the size of p, g, and h then allocate items */
5243 pghSize = L / 8;
5244
5245 pqg.base.data = vfy.h.data = NULL((void*)0);
5246 vfy.seed.len = pqg.base.len = vfy.h.len = 0;
5247 SECITEM_AllocItemSECITEM_AllocItem_Util(NULL((void*)0), &pqg.prime, pghSize);
5248 SECITEM_AllocItemSECITEM_AllocItem_Util(NULL((void*)0), &vfy.seed, pghSize * 3);
5249 if (type == A_2_2) {
5250 SECITEM_AllocItemSECITEM_AllocItem_Util(NULL((void*)0), &vfy.h, pghSize);
5251 vfy.h.len = pghSize;
5252 } else if (type == A_2_4) {
5253 SECITEM_AllocItemSECITEM_AllocItem_Util(NULL((void*)0), &vfy.h, 1);
5254 vfy.h.len = 1;
5255 }
5256 pqg.prime.len = pghSize;
5257 /* q is always N bits */
5258 SECITEM_AllocItemSECITEM_AllocItem_Util(NULL((void*)0), &pqg.subPrime, N / 8);
5259 pqg.subPrime.len = N / 8;
5260 vfy.counter = -1;
5261
5262 continue;
5263 }
5264 /* P = ... */
5265 if (buf[0] == 'P') {
5266 i = 1;
5267 while (isspace(buf[i])((*__ctype_b_loc ())[(int) ((buf[i]))] & (unsigned short int
) _ISspace)
|| buf[i] == '=') {
5268 i++;
5269 }
5270 for (j = 0; j < pqg.prime.len; i += 2, j++) {
5271 hex_to_byteval(&buf[i], &pqg.prime.data[j]);
5272 }
5273
5274 fputs(buf, dsaresp);
5275 continue;
5276 }
5277
5278 /* Q = ... */
5279 if (buf[0] == 'Q') {
5280 i = 1;
5281 while (isspace(buf[i])((*__ctype_b_loc ())[(int) ((buf[i]))] & (unsigned short int
) _ISspace)
|| buf[i] == '=') {
5282 i++;
5283 }
5284 for (j = 0; j < pqg.subPrime.len; i += 2, j++) {
5285 hex_to_byteval(&buf[i], &pqg.subPrime.data[j]);
5286 }
5287
5288 fputs(buf, dsaresp);
5289 continue;
5290 }
5291
5292 /* G = ... */
5293 if (buf[0] == 'G') {
5294 i = 1;
5295 if (pqg.base.data) {
5296 SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(&pqg.base, PR_FALSE0);
5297 }
5298 SECITEM_AllocItemSECITEM_AllocItem_Util(NULL((void*)0), &pqg.base, pghSize);
5299 while (isspace(buf[i])((*__ctype_b_loc ())[(int) ((buf[i]))] & (unsigned short int
) _ISspace)
|| buf[i] == '=') {
5300 i++;
5301 }
5302 for (j = 0; j < pqg.base.len; i += 2, j++) {
5303 hex_to_byteval(&buf[i], &pqg.base.data[j]);
5304 }
5305
5306 fputs(buf, dsaresp);
5307 continue;
5308 }
5309
5310 /* Seed = ... or domain_parameter_seed = ... */
5311 if (strncmp(buf, "Seed", 4) == 0) {
5312 i = 4;
5313 } else if (strncmp(buf, "domain_parameter_seed", 21) == 0) {
5314 i = 21;
5315 } else if (strncmp(buf, "firstseed", 9) == 0) {
5316 i = 9;
5317 } else {
5318 i = 0;
5319 }
5320 if (i) {
5321 while (isspace(buf[i])((*__ctype_b_loc ())[(int) ((buf[i]))] & (unsigned short int
) _ISspace)
|| buf[i] == '=') {
5322 i++;
5323 }
5324 for (j = 0; isxdigit(buf[i])((*__ctype_b_loc ())[(int) ((buf[i]))] & (unsigned short int
) _ISxdigit)
; i += 2, j++) {
5325 hex_to_byteval(&buf[i], &vfy.seed.data[j]);
5326 }
5327 vfy.seed.len = j;
5328
5329 fputs(buf, dsaresp);
5330 if (type == A_2_4) {
5331 SECStatus result;
5332
5333 /* Verify the Parameters */
5334 SECStatus rv = PQG_VerifyParams(&pqg, &vfy, &result);
5335 if (rv != SECSuccess) {
5336 goto loser;
5337 }
5338 if (result == SECSuccess) {
5339 fprintf(dsaresp, "Result = P\n");
5340 } else {
5341 fprintf(dsaresp, "Result = F\n");
5342 }
5343 }
5344 continue;
5345 }
5346 if ((strncmp(buf, "pseed", 5) == 0) ||
5347 (strncmp(buf, "qseed", 5) == 0)) {
5348 i = 5;
5349 while (isspace(buf[i])((*__ctype_b_loc ())[(int) ((buf[i]))] & (unsigned short int
) _ISspace)
|| buf[i] == '=') {
5350 i++;
5351 }
5352 for (j = vfy.seed.len; isxdigit(buf[i])((*__ctype_b_loc ())[(int) ((buf[i]))] & (unsigned short int
) _ISxdigit)
; i += 2, j++) {
5353 hex_to_byteval(&buf[i], &vfy.seed.data[j]);
5354 }
5355 vfy.seed.len = j;
5356 fputs(buf, dsaresp);
5357
5358 continue;
5359 }
5360 if (strncmp(buf, "index", 4) == 0) {
5361 i = 5;
5362 while (isspace(buf[i])((*__ctype_b_loc ())[(int) ((buf[i]))] & (unsigned short int
) _ISspace)
|| buf[i] == '=') {
5363 i++;
5364 }
5365 hex_to_byteval(&buf[i], &vfy.h.data[0]);
5366 vfy.h.len = 1;
5367 fputs(buf, dsaresp);
5368 }
5369
5370 /* c = ... or counter=*/
5371 if (buf[0] == 'c') {
5372 if (strncmp(buf, "counter", 7) == 0) {
5373 if (sscanf(buf, "counter = %u", &vfy.counter) != 1) {
5374 goto loser;
5375 }
5376 } else {
5377 if (sscanf(buf, "c = %u", &vfy.counter) != 1) {
5378 goto loser;
5379 }
5380 }
5381
5382 fputs(buf, dsaresp);
5383 if (type == A_1_1_3) {
5384 SECStatus result;
5385 /* only verify P and Q, we have everything now. do it */
5386 SECStatus rv = PQG_VerifyParams(&pqg, &vfy, &result);
5387 if (rv != SECSuccess) {
5388 goto loser;
5389 }
5390 if (result == SECSuccess) {
5391 fprintf(dsaresp, "Result = P\n");
5392 } else {
5393 fprintf(dsaresp, "Result = F\n");
5394 }
5395 fprintf(dsaresp, "\n");
5396 }
5397 continue;
5398 }
5399 if (strncmp(buf, "pgen_counter", 12) == 0) {
5400 if (sscanf(buf, "pgen_counter = %u", &vfy.counter) != 1) {
5401 goto loser;
5402 }
5403 fputs(buf, dsaresp);
5404 continue;
5405 }
5406 if (strncmp(buf, "qgen_counter", 12) == 0) {
5407 fputs(buf, dsaresp);
5408 if (type == A_1_2_2) {
5409 SECStatus result;
5410 /* only verify P and Q, we have everything now. do it */
5411 SECStatus rv = PQG_VerifyParams(&pqg, &vfy, &result);
5412 if (rv != SECSuccess) {
5413 goto loser;
5414 }
5415 if (result == SECSuccess) {
5416 fprintf(dsaresp, "Result = P\n");
5417 } else {
5418 fprintf(dsaresp, "Result = F\n");
5419 }
5420 fprintf(dsaresp, "\n");
5421 }
5422 continue;
5423 }
5424 /* H = ... */
5425 if (buf[0] == 'H') {
5426 SECStatus rv, result = SECFailure;
5427
5428 i = 1;
5429 while (isspace(buf[i])((*__ctype_b_loc ())[(int) ((buf[i]))] & (unsigned short int
) _ISspace)
|| buf[i] == '=') {
5430 i++;
5431 }
5432 for (j = 0; isxdigit(buf[i])((*__ctype_b_loc ())[(int) ((buf[i]))] & (unsigned short int
) _ISxdigit)
; i += 2, j++) {
5433 hex_to_byteval(&buf[i], &vfy.h.data[j]);
5434 }
5435 vfy.h.len = j;
5436 fputs(buf, dsaresp);
5437
5438 /* this should be a byte value. Remove the leading zeros. If
5439 * it doesn't reduce to a byte, PQG_VerifyParams will catch it
5440 if (type == A_2_2) {
5441 data_save = vfy.h.data;
5442 while(vfy.h.data[0] && (vfy.h.len > 1)) {
5443 vfy.h.data++;
5444 vfy.h.len--;
5445 }
5446 } */
5447
5448 /* Verify the Parameters */
5449 rv = PQG_VerifyParams(&pqg, &vfy, &result);
5450 if (rv != SECSuccess) {
5451 goto loser;
5452 }
5453 if (result == SECSuccess) {
5454 fprintf(dsaresp, "Result = P\n");
5455 } else {
5456 fprintf(dsaresp, "Result = F\n");
5457 }
5458 fprintf(dsaresp, "\n");
5459 continue;
5460 }
5461 }
5462loser:
5463 fclose(dsareq);
5464 if (pqg.prime.data) { /* P */
5465 SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(&pqg.prime, PR_FALSE0);
5466 }
5467 if (pqg.subPrime.data) { /* Q */
5468 SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(&pqg.subPrime, PR_FALSE0);
5469 }
5470 if (pqg.base.data) { /* G */
5471 SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(&pqg.base, PR_FALSE0);
5472 }
5473 if (vfy.seed.data) { /* seed */
5474 SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(&vfy.seed, PR_FALSE0);
5475 }
5476 if (vfy.h.data) { /* H */
5477 SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(&vfy.h, PR_FALSE0);
5478 }
5479}
5480
5481/*
5482 * Perform the DSA Public Key Validation Test.
5483 *
5484 * reqfn is the pathname of the REQUEST file.
5485 *
5486 * The output RESPONSE file is written to stdout.
5487 */
5488void
5489dsa_pqggen_test(char *reqfn)
5490{
5491 char buf[800]; /* holds one line from the input REQUEST file
5492 * or to the output RESPONSE file.
5493 * 800 to hold seed = (384 public key (x2 for HEX)
5494 */
5495 FILE *dsareq; /* input stream from the REQUEST file */
5496 FILE *dsaresp; /* output stream to the RESPONSE file */
5497 int count; /* number of times to generate parameters */
5498 int N;
5499 int L;
5500 int i;
5501 unsigned int j;
5502 int output_g = 1;
5503 PQGParams *pqg = NULL((void*)0);
5504 PQGVerify *vfy = NULL((void*)0);
5505 unsigned int keySizeIndex = 0;
5506 dsa_pqg_type type = FIPS186_1;
5507
5508 dsareq = fopen(reqfn, "r");
5509 dsaresp = stdoutstdout;
5510 while (fgets(buf, sizeof buf, dsareq) != NULL((void*)0)) {
5511 /* a comment or blank line */
5512 if (buf[0] == '#' || buf[0] == '\n') {
5513 fputs(buf, dsaresp);
5514 continue;
5515 }
5516
5517 /* [A.xxxxx ] */
5518 if (buf[0] == '[' && buf[1] == 'A') {
5519 if (strncmp(&buf[1], "A.1.1.2", 7) == 0) {
5520 fprintf(stderrstderr, "NSS does Generate Probablistic Primes\n");
5521 exit(1);
5522 } else if (strncmp(&buf[1], "A.2.1", 5) == 0) {
5523 type = A_1_2_1;
5524 output_g = 1;
5525 exit(1);
5526 } else if (strncmp(&buf[1], "A.2.3", 5) == 0) {
5527 fprintf(stderrstderr, "NSS only Generates G with P&Q\n");
5528 exit(1);
5529 } else if (strncmp(&buf[1], "A.1.2.1", 7) == 0) {
5530 type = A_1_2_1;
5531 output_g = 0;
5532 } else {
5533 fprintf(stderrstderr, "Unknown dsa pqggen test %s\n", &buf[1]);
5534 exit(1);
5535 }
5536 fputs(buf, dsaresp);
5537 continue;
5538 }
5539
5540 /* [Mod = ... ] */
5541 if (buf[0] == '[') {
5542
5543 if (type == FIPS186_1) {
5544 N = 160;
5545 if (sscanf(buf, "[mod = %d]", &L) != 1) {
5546 goto loser;
5547 }
5548 } else if (sscanf(buf, "[mod = L=%d, N=%d", &L, &N) != 2) {
5549 goto loser;
5550 }
5551
5552 fputs(buf, dsaresp);
5553 fputc('\n', dsaresp);
5554
5555 if (type == FIPS186_1) {
5556 /************************************************************
5557 * PQG_ParamGenSeedLen doesn't take a key size, it takes an
5558 * index that points to a valid key size.
5559 */
5560 keySizeIndex = PQG_PBITS_TO_INDEX(L)(((L) < 512 || (L) > 1024 || (L) % 64) ? -1 : (int)((L)
-512) / 64)
;
5561 if (keySizeIndex == -1 || L < 512 || L > 1024) {
5562 fprintf(dsaresp,
5563 "DSA key size must be a multiple of 64 between 512 "
5564 "and 1024, inclusive");
5565 goto loser;
5566 }
5567 }
5568 continue;
5569 }
5570 /* N = ... */
5571 if (buf[0] == 'N') {
5572 if (strncmp(buf, "Num", 3) == 0) {
5573 if (sscanf(buf, "Num = %d", &count) != 1) {
5574 goto loser;
5575 }
5576 } else if (sscanf(buf, "N = %d", &count) != 1) {
5577 goto loser;
5578 }
5579 for (i = 0; i < count; i++) {
5580 SECStatus rv;
5581
5582 if (type == FIPS186_1) {
5583 rv = PQG_ParamGenSeedLen(keySizeIndex, PQG_TEST_SEED_BYTES20,
5584 &pqg, &vfy);
5585 } else {
5586 rv = PQG_ParamGenV2(L, N, N, &pqg, &vfy);
5587 }
5588 if (rv != SECSuccess) {
5589 fprintf(dsaresp,
5590 "ERROR: Unable to generate PQG parameters");
5591 goto loser;
5592 }
5593 to_hex_str(buf, pqg->prime.data, pqg->prime.len);
5594 fprintf(dsaresp, "P = %s\n", buf);
5595 to_hex_str(buf, pqg->subPrime.data, pqg->subPrime.len);
5596 fprintf(dsaresp, "Q = %s\n", buf);
5597 if (output_g) {
5598 to_hex_str(buf, pqg->base.data, pqg->base.len);
5599 fprintf(dsaresp, "G = %s\n", buf);
5600 }
5601 if (type == FIPS186_1) {
5602 to_hex_str(buf, vfy->seed.data, vfy->seed.len);
5603 fprintf(dsaresp, "Seed = %s\n", buf);
5604 fprintf(dsaresp, "c = %d\n", vfy->counter);
5605 to_hex_str(buf, vfy->h.data, vfy->h.len);
5606 fputs("H = ", dsaresp);
5607 for (j = vfy->h.len; j < pqg->prime.len; j++) {
5608 fprintf(dsaresp, "00");
5609 }
5610 fprintf(dsaresp, "%s\n", buf);
5611 } else {
5612 unsigned int seedlen = vfy->seed.len / 2;
5613 unsigned int pgen_counter = vfy->counter >> 16;
5614 unsigned int qgen_counter = vfy->counter & 0xffff;
5615 /*fprintf(dsaresp, "index = %02x\n", vfy->h.data[0]); */
5616 to_hex_str(buf, vfy->seed.data, seedlen);
5617 fprintf(dsaresp, "pseed = %s\n", buf);
5618 to_hex_str(buf, vfy->seed.data + seedlen, seedlen);
5619 fprintf(dsaresp, "qseed = %s\n", buf);
5620 fprintf(dsaresp, "pgen_counter = %d\n", pgen_counter);
5621 fprintf(dsaresp, "qgen_counter = %d\n", qgen_counter);
5622 if (output_g) {
5623 to_hex_str(buf, vfy->seed.data, vfy->seed.len);
5624 fprintf(dsaresp, "domain_parameter_seed = %s\n", buf);
5625 fprintf(dsaresp, "index = %02x\n", vfy->h.data[0]);
5626 }
5627 }
5628 fputc('\n', dsaresp);
5629 if (pqg != NULL((void*)0)) {
5630 PQG_DestroyParams(pqg);
5631 pqg = NULL((void*)0);
5632 }
5633 if (vfy != NULL((void*)0)) {
5634 PQG_DestroyVerify(vfy);
5635 vfy = NULL((void*)0);
5636 }
5637 }
5638
5639 continue;
5640 }
5641 }
5642loser:
5643 fclose(dsareq);
5644 if (pqg != NULL((void*)0)) {
5645 PQG_DestroyParams(pqg);
5646 }
5647 if (vfy != NULL((void*)0)) {
5648 PQG_DestroyVerify(vfy);
5649 }
5650}
5651
5652/*
5653 * Perform the DSA Signature Generation Test.
5654 *
5655 * reqfn is the pathname of the REQUEST file.
5656 *
5657 * The output RESPONSE file is written to stdout.
5658 */
5659void
5660dsa_siggen_test(char *reqfn)
5661{
5662 char buf[800]; /* holds one line from the input REQUEST file
5663 * or to the output RESPONSE file.
5664 * max for Msg = ....
5665 */
5666 FILE *dsareq; /* input stream from the REQUEST file */
5667 FILE *dsaresp; /* output stream to the RESPONSE file */
5668 int modulus;
5669 int L;
5670 int N;
5671 int i, j;
5672 PRBool use_dsa1 = PR_FALSE0;
5673 PQGParams *pqg = NULL((void*)0);
5674 PQGVerify *vfy = NULL((void*)0);
5675 DSAPrivateKey *dsakey = NULL((void*)0);
5676 int keySizeIndex; /* index for valid key sizes */
5677 unsigned char hashBuf[HASH_LENGTH_MAX64]; /* SHA-x hash (160-512 bits) */
5678 unsigned char sig[DSA_MAX_SIGNATURE_LEN(32 * 2)];
5679 SECItem digest, signature;
5680 HASH_HashType hashType = HASH_AlgNULL;
5681 int hashNum = 0;
5682
5683 dsareq = fopen(reqfn, "r");
5684 dsaresp = stdoutstdout;
5685
5686 while (fgets(buf, sizeof buf, dsareq) != NULL((void*)0)) {
5687 /* a comment or blank line */
5688 if (buf[0] == '#' || buf[0] == '\n') {
5689 fputs(buf, dsaresp);
5690 continue;
5691 }
5692
5693 /* [Mod = x] */
5694 if (buf[0] == '[') {
5695 if (pqg != NULL((void*)0)) {
5696 PQG_DestroyParams(pqg);
5697 pqg = NULL((void*)0);
5698 }
5699 if (vfy != NULL((void*)0)) {
5700 PQG_DestroyVerify(vfy);
5701 vfy = NULL((void*)0);
5702 }
5703 if (dsakey != NULL((void*)0)) {
5704 PORT_FreeArenaPORT_FreeArena_Util(dsakey->params.arena, PR_TRUE1);
5705 dsakey = NULL((void*)0);
5706 }
5707
5708 if (sscanf(buf, "[mod = L=%d, N=%d, SHA-%d]", &L, &N,
5709 &hashNum) != 3) {
5710 use_dsa1 = PR_TRUE1;
5711 hashNum = 1;
5712 if (sscanf(buf, "[mod = %d]", &modulus) != 1) {
5713 goto loser;
5714 }
5715 }
5716 fputs(buf, dsaresp);
5717 fputc('\n', dsaresp);
5718
5719 /****************************************************************
5720 * PQG_ParamGenSeedLen doesn't take a key size, it takes an index
5721 * that points to a valid key size.
5722 */
5723 if (use_dsa1) {
5724 keySizeIndex = PQG_PBITS_TO_INDEX(modulus)(((modulus) < 512 || (modulus) > 1024 || (modulus) % 64
) ? -1 : (int)((modulus)-512) / 64)
;
5725 if (keySizeIndex == -1 || modulus < 512 || modulus > 1024) {
5726 fprintf(dsaresp,
5727 "DSA key size must be a multiple of 64 between 512 "
5728 "and 1024, inclusive");
5729 goto loser;
5730 }
5731 /* Generate PQG and output PQG */
5732 if (PQG_ParamGenSeedLen(keySizeIndex, PQG_TEST_SEED_BYTES20,
5733 &pqg, &vfy) !=
5734 SECSuccess) {
5735 fprintf(dsaresp,
5736 "ERROR: Unable to generate PQG parameters");
5737 goto loser;
5738 }
5739 } else {
5740 if (PQG_ParamGenV2(L, N, N, &pqg, &vfy) != SECSuccess) {
5741 fprintf(dsaresp,
5742 "ERROR: Unable to generate PQG parameters");
5743 goto loser;
5744 }
5745 }
5746 to_hex_str(buf, pqg->prime.data, pqg->prime.len);
5747 fprintf(dsaresp, "P = %s\n", buf);
5748 to_hex_str(buf, pqg->subPrime.data, pqg->subPrime.len);
5749 fprintf(dsaresp, "Q = %s\n", buf);
5750 to_hex_str(buf, pqg->base.data, pqg->base.len);
5751 fprintf(dsaresp, "G = %s\n", buf);
5752
5753 /* create DSA Key */
5754 if (DSA_NewKey(pqg, &dsakey) != SECSuccess) {
5755 fprintf(dsaresp, "ERROR: Unable to generate DSA key");
5756 goto loser;
5757 }
5758
5759 hashType = sha_get_hashType(hashNum);
5760 if (hashType == HASH_AlgNULL) {
5761 fprintf(dsaresp, "ERROR: invalid hash (SHA-%d)", hashNum);
5762 goto loser;
5763 }
5764 continue;
5765 }
5766
5767 /* Msg = ... */
5768 if (strncmp(buf, "Msg", 3) == 0) {
5769 unsigned char msg[128]; /* MAX msg 128 */
5770 unsigned int len = 0;
5771
5772 if (hashType == HASH_AlgNULL) {
5773 fprintf(dsaresp, "ERROR: Hash Alg not set");
5774 goto loser;
5775 }
5776
5777 memset(hashBuf, 0, sizeof hashBuf);
5778 memset(sig, 0, sizeof sig);
5779
5780 i = 3;
5781 while (isspace(buf[i])((*__ctype_b_loc ())[(int) ((buf[i]))] & (unsigned short int
) _ISspace)
|| buf[i] == '=') {
5782 i++;
5783 }
5784 for (j = 0; isxdigit(buf[i])((*__ctype_b_loc ())[(int) ((buf[i]))] & (unsigned short int
) _ISxdigit)
; i += 2, j++) {
5785 hex_to_byteval(&buf[i], &msg[j]);
5786 }
5787 if (fips_hashBuf(hashType, hashBuf, msg, j) != SECSuccess) {
5788 fprintf(dsaresp, "ERROR: Unable to generate SHA% digest",
5789 hashNum);
5790 goto loser;
5791 }
5792
5793 digest.type = siBuffer;
5794 digest.data = hashBuf;
5795 digest.len = fips_hashLen(hashType);
5796 signature.type = siBuffer;
5797 signature.data = sig;
5798 signature.len = sizeof sig;
5799
5800 if (DSA_SignDigest(dsakey, &signature, &digest) != SECSuccess) {
5801 fprintf(dsaresp, "ERROR: Unable to generate DSA signature");
5802 goto loser;
5803 }
5804 len = signature.len;
5805 if (len % 2 != 0) {
5806 goto loser;
5807 }
5808 len = len / 2;
5809
5810 /* output the orginal Msg, and generated Y, R, and S */
5811 fputs(buf, dsaresp);
5812 to_hex_str(buf, dsakey->publicValue.data,
5813 dsakey->publicValue.len);
5814 fprintf(dsaresp, "Y = %s\n", buf);
5815 to_hex_str(buf, &signature.data[0], len);
5816 fprintf(dsaresp, "R = %s\n", buf);
5817 to_hex_str(buf, &signature.data[len], len);
5818 fprintf(dsaresp, "S = %s\n", buf);
5819 fputc('\n', dsaresp);
5820 continue;
5821 }
5822 }
5823loser:
5824 fclose(dsareq);
5825 if (pqg != NULL((void*)0)) {
5826 PQG_DestroyParams(pqg);
5827 pqg = NULL((void*)0);
5828 }
5829 if (vfy != NULL((void*)0)) {
5830 PQG_DestroyVerify(vfy);
5831 vfy = NULL((void*)0);
5832 }
5833 if (dsakey) {
5834 PORT_FreeArenaPORT_FreeArena_Util(dsakey->params.arena, PR_TRUE1);
5835 dsakey = NULL((void*)0);
5836 }
5837}
5838
5839/*
5840 * Perform the DSA Signature Verification Test.
5841 *
5842 * reqfn is the pathname of the REQUEST file.
5843 *
5844 * The output RESPONSE file is written to stdout.
5845 */
5846void
5847dsa_sigver_test(char *reqfn)
5848{
5849 char buf[800]; /* holds one line from the input REQUEST file
5850 * or to the output RESPONSE file.
5851 * max for Msg = ....
5852 */
5853 FILE *dsareq; /* input stream from the REQUEST file */
5854 FILE *dsaresp; /* output stream to the RESPONSE file */
5855 int L;
5856 int N;
5857 unsigned int i, j;
5858 SECItem digest, signature;
5859 DSAPublicKey pubkey;
5860 unsigned int pgySize; /* size for p, g, and y */
5861 unsigned char hashBuf[HASH_LENGTH_MAX64]; /* SHA-x hash (160-512 bits) */
5862 unsigned char sig[DSA_MAX_SIGNATURE_LEN(32 * 2)];
5863 HASH_HashType hashType = HASH_AlgNULL;
5864 int hashNum = 0;
5865
5866 dsareq = fopen(reqfn, "r");
5867 dsaresp = stdoutstdout;
5868 memset(&pubkey, 0, sizeof(pubkey));
5869
5870 while (fgets(buf, sizeof buf, dsareq) != NULL((void*)0)) {
5871 /* a comment or blank line */
5872 if (buf[0] == '#' || buf[0] == '\n') {
5873 fputs(buf, dsaresp);
5874 continue;
5875 }
5876
5877 /* [Mod = x] */
5878 if (buf[0] == '[') {
5879
5880 if (sscanf(buf, "[mod = L=%d, N=%d, SHA-%d]", &L, &N,
5881 &hashNum) != 3) {
5882 N = 160;
5883 hashNum = 1;
5884 if (sscanf(buf, "[mod = %d]", &L) != 1) {
5885 goto loser;
5886 }
5887 }
5888
5889 if (pubkey.params.prime.data) { /* P */
5890 SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(&pubkey.params.prime, PR_FALSE0);
5891 }
5892 if (pubkey.params.subPrime.data) { /* Q */
5893 SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(&pubkey.params.subPrime, PR_FALSE0);
5894 }
5895 if (pubkey.params.base.data) { /* G */
5896 SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(&pubkey.params.base, PR_FALSE0);
5897 }
5898 if (pubkey.publicValue.data) { /* Y */
5899 SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(&pubkey.publicValue, PR_FALSE0);
5900 }
5901 fputs(buf, dsaresp);
5902
5903 /* calculate the size of p, g, and y then allocate items */
5904 pgySize = L / 8;
5905 SECITEM_AllocItemSECITEM_AllocItem_Util(NULL((void*)0), &pubkey.params.prime, pgySize);
5906 SECITEM_AllocItemSECITEM_AllocItem_Util(NULL((void*)0), &pubkey.params.base, pgySize);
5907 SECITEM_AllocItemSECITEM_AllocItem_Util(NULL((void*)0), &pubkey.publicValue, pgySize);
5908 pubkey.params.prime.len = pubkey.params.base.len = pgySize;
5909 pubkey.publicValue.len = pgySize;
5910
5911 /* q always N/8 bytes */
5912 SECITEM_AllocItemSECITEM_AllocItem_Util(NULL((void*)0), &pubkey.params.subPrime, N / 8);
5913 pubkey.params.subPrime.len = N / 8;
5914
5915 hashType = sha_get_hashType(hashNum);
5916 if (hashType == HASH_AlgNULL) {
5917 fprintf(dsaresp, "ERROR: invalid hash (SHA-%d)", hashNum);
5918 goto loser;
5919 }
5920
5921 continue;
5922 }
5923 /* P = ... */
5924 if (buf[0] == 'P') {
5925 i = 1;
5926 while (isspace(buf[i])((*__ctype_b_loc ())[(int) ((buf[i]))] & (unsigned short int
) _ISspace)
|| buf[i] == '=') {
5927 i++;
5928 }
5929 memset(pubkey.params.prime.data, 0, pubkey.params.prime.len);
5930 for (j = 0; j < pubkey.params.prime.len; i += 2, j++) {
5931 hex_to_byteval(&buf[i], &pubkey.params.prime.data[j]);
5932 }
5933
5934 fputs(buf, dsaresp);
5935 continue;
5936 }
5937
5938 /* Q = ... */
5939 if (buf[0] == 'Q') {
5940 i = 1;
5941 while (isspace(buf[i])((*__ctype_b_loc ())[(int) ((buf[i]))] & (unsigned short int
) _ISspace)
|| buf[i] == '=') {
5942 i++;
5943 }
5944 memset(pubkey.params.subPrime.data, 0, pubkey.params.subPrime.len);
5945 for (j = 0; j < pubkey.params.subPrime.len; i += 2, j++) {
5946 hex_to_byteval(&buf[i], &pubkey.params.subPrime.data[j]);
5947 }
5948
5949 fputs(buf, dsaresp);
5950 continue;
5951 }
5952
5953 /* G = ... */
5954 if (buf[0] == 'G') {
5955 i = 1;
5956 while (isspace(buf[i])((*__ctype_b_loc ())[(int) ((buf[i]))] & (unsigned short int
) _ISspace)
|| buf[i] == '=') {
5957 i++;
5958 }
5959 memset(pubkey.params.base.data, 0, pubkey.params.base.len);
5960 for (j = 0; j < pubkey.params.base.len; i += 2, j++) {
5961 hex_to_byteval(&buf[i], &pubkey.params.base.data[j]);
5962 }
5963
5964 fputs(buf, dsaresp);
5965 continue;
5966 }
5967
5968 /* Msg = ... */
5969 if (strncmp(buf, "Msg", 3) == 0) {
5970 unsigned char msg[128]; /* MAX msg 128 */
5971 memset(hashBuf, 0, sizeof hashBuf);
5972
5973 if (hashType == HASH_AlgNULL) {
5974 fprintf(dsaresp, "ERROR: Hash Alg not set");
5975 goto loser;
5976 }
5977
5978 i = 3;
5979 while (isspace(buf[i])((*__ctype_b_loc ())[(int) ((buf[i]))] & (unsigned short int
) _ISspace)
|| buf[i] == '=') {
5980 i++;
5981 }
5982 for (j = 0; isxdigit(buf[i])((*__ctype_b_loc ())[(int) ((buf[i]))] & (unsigned short int
) _ISxdigit)
; i += 2, j++) {
5983 hex_to_byteval(&buf[i], &msg[j]);
5984 }
5985 if (fips_hashBuf(hashType, hashBuf, msg, j) != SECSuccess) {
5986 fprintf(dsaresp, "ERROR: Unable to generate SHA-%d digest",
5987 hashNum);
5988 goto loser;
5989 }
5990
5991 fputs(buf, dsaresp);
5992 continue;
5993 }
5994
5995 /* Y = ... */
5996 if (buf[0] == 'Y') {
5997 i = 1;
5998 while (isspace(buf[i])((*__ctype_b_loc ())[(int) ((buf[i]))] & (unsigned short int
) _ISspace)
|| buf[i] == '=') {
5999 i++;
6000 }
6001 memset(pubkey.publicValue.data, 0, pubkey.params.subPrime.len);
6002 for (j = 0; j < pubkey.publicValue.len; i += 2, j++) {
6003 hex_to_byteval(&buf[i], &pubkey.publicValue.data[j]);
6004 }
6005
6006 fputs(buf, dsaresp);
6007 continue;
6008 }
6009
6010 /* R = ... */
6011 if (buf[0] == 'R') {
6012 memset(sig, 0, sizeof sig);
6013 i = 1;
6014 while (isspace(buf[i])((*__ctype_b_loc ())[(int) ((buf[i]))] & (unsigned short int
) _ISspace)
|| buf[i] == '=') {
6015 i++;
6016 }
6017 for (j = 0; j < pubkey.params.subPrime.len; i += 2, j++) {
6018 hex_to_byteval(&buf[i], &sig[j]);
6019 }
6020
6021 fputs(buf, dsaresp);
6022 continue;
6023 }
6024
6025 /* S = ... */
6026 if (buf[0] == 'S') {
6027 if (hashType == HASH_AlgNULL) {
6028 fprintf(dsaresp, "ERROR: Hash Alg not set");
6029 goto loser;
6030 }
6031
6032 i = 1;
6033 while (isspace(buf[i])((*__ctype_b_loc ())[(int) ((buf[i]))] & (unsigned short int
) _ISspace)
|| buf[i] == '=') {
6034 i++;
6035 }
6036 for (j = pubkey.params.subPrime.len;
6037 j < pubkey.params.subPrime.len * 2; i += 2, j++) {
6038 hex_to_byteval(&buf[i], &sig[j]);
6039 }
6040 fputs(buf, dsaresp);
6041
6042 digest.type = siBuffer;
6043 digest.data = hashBuf;
6044 digest.len = fips_hashLen(hashType);
6045 signature.type = siBuffer;
6046 signature.data = sig;
6047 signature.len = pubkey.params.subPrime.len * 2;
6048
6049 if (DSA_VerifyDigest(&pubkey, &signature, &digest) == SECSuccess) {
6050 fprintf(dsaresp, "Result = P\n");
6051 } else {
6052 fprintf(dsaresp, "Result = F\n");
6053 }
6054 fprintf(dsaresp, "\n");
6055 continue;
6056 }
6057 }
6058loser:
6059 fclose(dsareq);
6060 if (pubkey.params.prime.data) { /* P */
6061 SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(&pubkey.params.prime, PR_FALSE0);
6062 }
6063 if (pubkey.params.subPrime.data) { /* Q */
6064 SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(&pubkey.params.subPrime, PR_FALSE0);
6065 }
6066 if (pubkey.params.base.data) { /* G */
6067 SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(&pubkey.params.base, PR_FALSE0);
6068 }
6069 if (pubkey.publicValue.data) { /* Y */
6070 SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(&pubkey.publicValue, PR_FALSE0);
6071 }
6072}
6073
6074static void
6075pad(unsigned char *buf, int pad_len, unsigned char *src, int src_len)
6076{
6077 int offset = 0;
6078 /* this shouldn't happen, fail right away rather than produce bad output */
6079 if (pad_len < src_len) {
6080 fprintf(stderrstderr, "data bigger than expected! %d > %d\n", src_len, pad_len);
6081 exit(1);
6082 }
6083
6084 offset = pad_len - src_len;
6085 memset(buf, 0, offset);
6086 memcpy(buf + offset, src, src_len);
6087 return;
6088}
6089
6090/*
6091 * Perform the DSA Key Pair Generation Test.
6092 *
6093 * reqfn is the pathname of the REQUEST file.
6094 *
6095 * The output RESPONSE file is written to stdout.
6096 */
6097void
6098rsa_keypair_test(char *reqfn)
6099{
6100 char buf[800]; /* holds one line from the input REQUEST file
6101 * or to the output RESPONSE file.
6102 * 800 to hold (384 public key (x2 for HEX) + 1'\n'
6103 */
6104 unsigned char buf2[400]; /* can't need more then 1/2 buf length */
6105 FILE *rsareq; /* input stream from the REQUEST file */
6106 FILE *rsaresp; /* output stream to the RESPONSE file */
6107 int count;
6108 int i;
6109 int keySize = 1; /* key size in bits*/
6110 int len = 0; /* key size in bytes */
6111 int len2 = 0; /* key size in bytes/2 (prime size) */
6112 SECItem e;
6113 unsigned char default_e[] = { 0x1, 0x0, 0x1 };
6114
6115 e.data = default_e;
6116 e.len = sizeof(default_e);
6117
6118 rsareq = fopen(reqfn, "r");
6119 rsaresp = stdoutstdout;
6120 while (fgets(buf, sizeof buf, rsareq) != NULL((void*)0)) {
6121 /* a comment or blank line */
6122 if (buf[0] == '#' || buf[0] == '\n') {
6123 fputs(buf, rsaresp);
6124 continue;
6125 }
6126
6127 /* [Mod = x] */
6128 if (buf[0] == '[') {
6129 if (buf[1] == 'm') {
6130 if (sscanf(buf, "[mod = %d]", &keySize) != 1) {
6131 goto loser;
6132 }
6133 len = keySize / 8;
6134 len2 = keySize / 16;
6135 }
6136 fputs(buf, rsaresp);
6137 continue;
6138 }
6139 /* N = ...*/
6140 if (buf[0] == 'N') {
6141
6142 if (sscanf(buf, "N = %d", &count) != 1) {
6143 goto loser;
6144 }
6145
6146 /* Generate a DSA key, and output the key pair for N times */
6147 for (i = 0; i < count; i++) {
6148 RSAPrivateKey *rsakey = NULL((void*)0);
6149 if ((rsakey = RSA_NewKey(keySize, &e)) == NULL((void*)0)) {
6150 fprintf(rsaresp, "ERROR: Unable to generate RSA key");
6151 goto loser;
6152 }
6153 pad(buf2, len, rsakey->publicExponent.data,
6154 rsakey->publicExponent.len);
6155 to_hex_str(buf, buf2, len);
6156 fprintf(rsaresp, "e = %s\n", buf);
6157 pad(buf2, len2, rsakey->prime1.data,
6158 rsakey->prime1.len);
6159 to_hex_str(buf, buf2, len2);
6160 fprintf(rsaresp, "p = %s\n", buf);
6161 pad(buf2, len2, rsakey->prime2.data,
6162 rsakey->prime2.len);
6163 to_hex_str(buf, buf2, len2);
6164 fprintf(rsaresp, "q = %s\n", buf);
6165 pad(buf2, len, rsakey->modulus.data,
6166 rsakey->modulus.len);
6167 to_hex_str(buf, buf2, len);
6168 fprintf(rsaresp, "n = %s\n", buf);
6169 pad(buf2, len, rsakey->privateExponent.data,
6170 rsakey->privateExponent.len);
6171 to_hex_str(buf, buf2, len);
6172 fprintf(rsaresp, "d = %s\n", buf);
6173 fprintf(rsaresp, "\n");
6174 PORT_FreeArenaPORT_FreeArena_Util(rsakey->arena, PR_TRUE1);
6175 rsakey = NULL((void*)0);
6176 }
6177 continue;
6178 }
6179 }
6180loser:
6181 fclose(rsareq);
6182}
6183
6184/*
6185 * Perform the RSA Signature Generation Test.
6186 *
6187 * reqfn is the pathname of the REQUEST file.
6188 *
6189 * The output RESPONSE file is written to stdout.
6190 */
6191void
6192rsa_siggen_test(char *reqfn)
6193{
6194 char buf[2 * RSA_MAX_TEST_MODULUS_BYTES4096 / 8 + 1];
6195 /* buf holds one line from the input REQUEST file
6196 * or to the output RESPONSE file.
6197 * 2x for HEX output + 1 for \n
6198 */
6199 FILE *rsareq; /* input stream from the REQUEST file */
6200 FILE *rsaresp; /* output stream to the RESPONSE file */
6201 int i, j;
6202 unsigned char sha[HASH_LENGTH_MAX64]; /* SHA digest */
6203 unsigned int shaLength = 0; /* length of SHA */
6204 HASH_HashType shaAlg = HASH_AlgNULL; /* type of SHA Alg */
6205 SECOidTag shaOid = SEC_OID_UNKNOWN;
6206 int modulus; /* the Modulus size */
6207 int publicExponent = DEFAULT_RSA_PUBLIC_EXPONENT0x10001;
6208 SECItem pe = { 0, 0, 0 };
6209 unsigned char pubEx[4];
6210 int peCount = 0;
6211
6212 RSAPrivateKey *rsaBlapiPrivKey = NULL((void*)0); /* holds RSA private and
6213 * public keys */
6214 RSAPublicKey *rsaBlapiPublicKey = NULL((void*)0); /* hold RSA public key */
6215
6216 rsareq = fopen(reqfn, "r");
6217 rsaresp = stdoutstdout;
6218
6219 /* calculate the exponent */
6220 for (i = 0; i < 4; i++) {
6221 if (peCount || (publicExponent &
6222 ((unsigned long)0xff000000L >> (i *
6223 8)))) {
6224 pubEx[peCount] =
6225 (unsigned char)((publicExponent >> (3 - i) * 8) & 0xff);
6226 peCount++;
6227 }
6228 }
6229 pe.len = peCount;
6230 pe.data = &pubEx[0];
6231 pe.type = siBuffer;
6232
6233 while (fgets(buf, sizeof buf, rsareq) != NULL((void*)0)) {
6234 /* a comment or blank line */
6235 if (buf[0] == '#' || buf[0] == '\n') {
6236 fputs(buf, rsaresp);
6237 continue;
6238 }
6239
6240 /* [mod = ...] */
6241 if (buf[0] == '[') {
6242
6243 if (sscanf(buf, "[mod = %d]", &modulus) != 1) {
6244 goto loser;
6245 }
6246 if (modulus > RSA_MAX_TEST_MODULUS_BITS4096) {
6247 fprintf(rsaresp, "ERROR: modulus greater than test maximum\n");
6248 goto loser;
6249 }
6250
6251 fputs(buf, rsaresp);
6252
6253 if (rsaBlapiPrivKey != NULL((void*)0)) {
6254 PORT_FreeArenaPORT_FreeArena_Util(rsaBlapiPrivKey->arena, PR_TRUE1);
6255 rsaBlapiPrivKey = NULL((void*)0);
6256 rsaBlapiPublicKey = NULL((void*)0);
6257 }
6258
6259 rsaBlapiPrivKey = RSA_NewKey(modulus, &pe);
6260 if (rsaBlapiPrivKey == NULL((void*)0)) {
6261 fprintf(rsaresp, "Error unable to create RSA key\n");
6262 goto loser;
6263 }
6264
6265 to_hex_str(buf, rsaBlapiPrivKey->modulus.data,
6266 rsaBlapiPrivKey->modulus.len);
6267 fprintf(rsaresp, "\nn = %s\n\n", buf);
6268 to_hex_str(buf, rsaBlapiPrivKey->publicExponent.data,
6269 rsaBlapiPrivKey->publicExponent.len);
6270 fprintf(rsaresp, "e = %s\n", buf);
6271 /* convert private key to public key. Memory
6272 * is freed with private key's arena */
6273 rsaBlapiPublicKey = (RSAPublicKey *)PORT_ArenaAllocPORT_ArenaAlloc_Util(
6274 rsaBlapiPrivKey->arena,
6275 sizeof(RSAPublicKey));
6276
6277 rsaBlapiPublicKey->modulus.len = rsaBlapiPrivKey->modulus.len;
6278 rsaBlapiPublicKey->modulus.data = rsaBlapiPrivKey->modulus.data;
6279 rsaBlapiPublicKey->publicExponent.len =
6280 rsaBlapiPrivKey->publicExponent.len;
6281 rsaBlapiPublicKey->publicExponent.data =
6282 rsaBlapiPrivKey->publicExponent.data;
6283 continue;
6284 }
6285
6286 /* SHAAlg = ... */
6287 if (strncmp(buf, "SHAAlg", 6) == 0) {
6288 i = 6;
6289 while (isspace(buf[i])((*__ctype_b_loc ())[(int) ((buf[i]))] & (unsigned short int
) _ISspace)
|| buf[i] == '=') {
6290 i++;
6291 }
6292 /* set the SHA Algorithm */
6293 shaAlg = hash_string_to_hashType(&buf[i]);
6294 if (shaAlg == HASH_AlgNULL) {
6295 fprintf(rsaresp, "ERROR: Unable to find SHAAlg type");
6296 goto loser;
6297 }
6298 fputs(buf, rsaresp);
6299 continue;
6300 }
6301 /* Msg = ... */
6302 if (strncmp(buf, "Msg", 3) == 0) {
6303
6304 unsigned char msg[128]; /* MAX msg 128 */
6305 unsigned int rsa_bytes_signed;
6306 unsigned char rsa_computed_signature[RSA_MAX_TEST_MODULUS_BYTES4096 / 8];
6307 SECStatus rv = SECFailure;
6308 NSSLOWKEYPublicKey *rsa_public_key;
6309 NSSLOWKEYPrivateKey *rsa_private_key;
6310 NSSLOWKEYPrivateKey low_RSA_private_key = { NULL((void*)0),
6311 NSSLOWKEYRSAKey };
6312 NSSLOWKEYPublicKey low_RSA_public_key = { NULL((void*)0),
6313 NSSLOWKEYRSAKey };
6314
6315 low_RSA_private_key.u.rsa = *rsaBlapiPrivKey;
6316 low_RSA_public_key.u.rsa = *rsaBlapiPublicKey;
6317
6318 rsa_private_key = &low_RSA_private_key;
6319 rsa_public_key = &low_RSA_public_key;
6320
6321 memset(sha, 0, sizeof sha);
6322 memset(msg, 0, sizeof msg);
6323 rsa_bytes_signed = 0;
6324 memset(rsa_computed_signature, 0, sizeof rsa_computed_signature);
6325
6326 i = 3;
6327 while (isspace(buf[i])((*__ctype_b_loc ())[(int) ((buf[i]))] & (unsigned short int
) _ISspace)
|| buf[i] == '=') {
6328 i++;
6329 }
6330 for (j = 0; isxdigit(buf[i])((*__ctype_b_loc ())[(int) ((buf[i]))] & (unsigned short int
) _ISxdigit)
&& j < sizeof(msg); i += 2, j++) {
6331 hex_to_byteval(&buf[i], &msg[j]);
6332 }
6333 shaLength = fips_hashLen(shaAlg);
6334 if (fips_hashBuf(shaAlg, sha, msg, j) != SECSuccess) {
6335 if (shaLength == 0) {
6336 fprintf(rsaresp, "ERROR: SHAAlg not defined.");
6337 }
6338 fprintf(rsaresp, "ERROR: Unable to generate SHA%x",
6339 shaLength == 160 ? 1 : shaLength);
6340 goto loser;
6341 }
6342 shaOid = fips_hashOid(shaAlg);
6343
6344 /* Perform RSA signature with the RSA private key. */
6345 rv = RSA_HashSign(shaOid,
6346 rsa_private_key,
6347 rsa_computed_signature,
6348 &rsa_bytes_signed,
6349 nsslowkey_PrivateModulusLen(rsa_private_key),
6350 sha,
6351 shaLength);
6352
6353 if (rv != SECSuccess) {
6354 fprintf(rsaresp, "ERROR: RSA_HashSign failed");
6355 goto loser;
6356 }
6357
6358 /* Output the signature */
6359 fputs(buf, rsaresp);
6360 to_hex_str(buf, rsa_computed_signature, rsa_bytes_signed);
6361 fprintf(rsaresp, "S = %s\n", buf);
6362
6363 /* Perform RSA verification with the RSA public key. */
6364 rv = RSA_HashCheckSign(shaOid,
6365 rsa_public_key,
6366 rsa_computed_signature,
6367 rsa_bytes_signed,
6368 sha,
6369 shaLength);
6370 if (rv != SECSuccess) {
6371 fprintf(rsaresp, "ERROR: RSA_HashCheckSign failed");
6372 goto loser;
6373 }
6374 continue;
6375 }
6376 }
6377loser:
6378 fclose(rsareq);
6379
6380 if (rsaBlapiPrivKey != NULL((void*)0)) {
6381 /* frees private and public key */
6382 PORT_FreeArenaPORT_FreeArena_Util(rsaBlapiPrivKey->arena, PR_TRUE1);
6383 rsaBlapiPrivKey = NULL((void*)0);
6384 rsaBlapiPublicKey = NULL((void*)0);
6385 }
6386}
6387/*
6388 * Perform the RSA Signature Verification Test.
6389 *
6390 * reqfn is the pathname of the REQUEST file.
6391 *
6392 * The output RESPONSE file is written to stdout.
6393 */
6394void
6395rsa_sigver_test(char *reqfn)
6396{
6397 char buf[2 * RSA_MAX_TEST_MODULUS_BYTES4096 / 8 + 7];
6398 /* buf holds one line from the input REQUEST file
6399 * or to the output RESPONSE file.
6400 * s = 2x for HEX output + 1 for \n
6401 */
6402 FILE *rsareq; /* input stream from the REQUEST file */
6403 FILE *rsaresp; /* output stream to the RESPONSE file */
6404 int i, j;
6405 unsigned char sha[HASH_LENGTH_MAX64]; /* SHA digest */
6406 unsigned int shaLength = 0; /* actual length of the digest */
6407 HASH_HashType shaAlg = HASH_AlgNULL;
6408 SECOidTag shaOid = SEC_OID_UNKNOWN;
6409 int modulus = 0; /* the Modulus size */
6410 unsigned char signature[513]; /* largest signature size + '\n' */
6411 unsigned int signatureLength = 0; /* actual length of the signature */
6412 PRBool keyvalid = PR_TRUE1;
6413
6414 RSAPublicKey rsaBlapiPublicKey; /* hold RSA public key */
6415
6416 rsareq = fopen(reqfn, "r");
6417 rsaresp = stdoutstdout;
6418 memset(&rsaBlapiPublicKey, 0, sizeof(RSAPublicKey));
6419
6420 while (fgets(buf, sizeof buf, rsareq) != NULL((void*)0)) {
6421 /* a comment or blank line */
6422 if (buf[0] == '#' || buf[0] == '\n') {
6423 fputs(buf, rsaresp);
6424 continue;
6425 }
6426
6427 /* [Mod = ...] */
6428 if (buf[0] == '[') {
6429 unsigned int flen; /* length in bytes of the field size */
6430
6431 if (rsaBlapiPublicKey.modulus.data) { /* n */
6432 SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(&rsaBlapiPublicKey.modulus, PR_FALSE0);
6433 }
6434 if (sscanf(buf, "[mod = %d]", &modulus) != 1) {
6435 goto loser;
6436 }
6437
6438 if (modulus > RSA_MAX_TEST_MODULUS_BITS4096) {
6439 fprintf(rsaresp, "ERROR: modulus greater than test maximum\n");
6440 goto loser;
6441 }
6442
6443 fputs(buf, rsaresp);
6444
6445 signatureLength = flen = modulus / 8;
6446
6447 SECITEM_AllocItemSECITEM_AllocItem_Util(NULL((void*)0), &rsaBlapiPublicKey.modulus, flen);
6448 if (rsaBlapiPublicKey.modulus.data == NULL((void*)0)) {
6449 goto loser;
6450 }
6451 continue;
6452 }
6453
6454 /* n = ... modulus */
6455 if (buf[0] == 'n') {
6456 i = 1;
6457 while (isspace(buf[i])((*__ctype_b_loc ())[(int) ((buf[i]))] & (unsigned short int
) _ISspace)
|| buf[i] == '=') {
6458 i++;
6459 }
6460 keyvalid = from_hex_str(&rsaBlapiPublicKey.modulus.data[0],
6461 rsaBlapiPublicKey.modulus.len,
6462 &buf[i]);
6463
6464 if (!keyvalid) {
6465 fprintf(rsaresp, "ERROR: rsa_sigver n not valid.\n");
6466 goto loser;
6467 }
6468 fputs(buf, rsaresp);
6469 continue;
6470 }
6471
6472 /* SHAAlg = ... */
6473 if (strncmp(buf, "SHAAlg", 6) == 0) {
6474 i = 6;
6475 while (isspace(buf[i])((*__ctype_b_loc ())[(int) ((buf[i]))] & (unsigned short int
) _ISspace)
|| buf[i] == '=') {
6476 i++;
6477 }
6478 /* set the SHA Algorithm */
6479 shaAlg = hash_string_to_hashType(&buf[i]);
6480 if (shaAlg == HASH_AlgNULL) {
6481 fprintf(rsaresp, "ERROR: Unable to find SHAAlg type");
6482 goto loser;
6483 }
6484 fputs(buf, rsaresp);
6485 continue;
6486 }
6487
6488 /* e = ... public Key */
6489 if (buf[0] == 'e') {
6490 unsigned char data[RSA_MAX_TEST_EXPONENT_BYTES8];
6491 unsigned char t;
6492
6493 memset(data, 0, sizeof data);
6494
6495 if (rsaBlapiPublicKey.publicExponent.data) { /* e */
6496 SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(&rsaBlapiPublicKey.publicExponent, PR_FALSE0);
6497 }
6498
6499 i = 1;
6500 while (isspace(buf[i])((*__ctype_b_loc ())[(int) ((buf[i]))] & (unsigned short int
) _ISspace)
|| buf[i] == '=') {
6501 i++;
6502 }
6503 /* skip leading zero's */
6504 while (isxdigit(buf[i])((*__ctype_b_loc ())[(int) ((buf[i]))] & (unsigned short int
) _ISxdigit)
) {
6505 hex_to_byteval(&buf[i], &t);
6506 if (t == 0) {
6507 i += 2;
6508 } else
6509 break;
6510 }
6511
6512 /* get the exponent */
6513 for (j = 0; isxdigit(buf[i])((*__ctype_b_loc ())[(int) ((buf[i]))] & (unsigned short int
) _ISxdigit)
&& j < sizeof data; i += 2, j++) {
6514 hex_to_byteval(&buf[i], &data[j]);
6515 }
6516
6517 if (j == 0) {
6518 j = 1;
6519 } /* to handle 1 byte length exponents */
6520
6521 SECITEM_AllocItemSECITEM_AllocItem_Util(NULL((void*)0), &rsaBlapiPublicKey.publicExponent, j);
6522 if (rsaBlapiPublicKey.publicExponent.data == NULL((void*)0)) {
6523 goto loser;
6524 }
6525
6526 for (i = 0; i < j; i++) {
6527 rsaBlapiPublicKey.publicExponent.data[i] = data[i];
6528 }
6529
6530 fputs(buf, rsaresp);
6531 continue;
6532 }
6533
6534 /* Msg = ... */
6535 if (strncmp(buf, "Msg", 3) == 0) {
6536 unsigned char msg[128]; /* MAX msg 128 */
6537
6538 memset(sha, 0, sizeof sha);
6539 memset(msg, 0, sizeof msg);
6540
6541 i = 3;
6542 while (isspace(buf[i])((*__ctype_b_loc ())[(int) ((buf[i]))] & (unsigned short int
) _ISspace)
|| buf[i] == '=') {
6543 i++;
6544 }
6545
6546 for (j = 0; isxdigit(buf[i])((*__ctype_b_loc ())[(int) ((buf[i]))] & (unsigned short int
) _ISxdigit)
&& j < sizeof msg; i += 2, j++) {
6547 hex_to_byteval(&buf[i], &msg[j]);
6548 }
6549
6550 shaLength = fips_hashLen(shaAlg);
6551 if (fips_hashBuf(shaAlg, sha, msg, j) != SECSuccess) {
6552 if (shaLength == 0) {
6553 fprintf(rsaresp, "ERROR: SHAAlg not defined.");
6554 }
6555 fprintf(rsaresp, "ERROR: Unable to generate SHA%x",
6556 shaLength == 160 ? 1 : shaLength);
6557 goto loser;
6558 }
6559
6560 fputs(buf, rsaresp);
6561 continue;
6562 }
6563
6564 /* S = ... */
6565 if (buf[0] == 'S') {
6566 SECStatus rv = SECFailure;
6567 NSSLOWKEYPublicKey *rsa_public_key;
6568 NSSLOWKEYPublicKey low_RSA_public_key = { NULL((void*)0),
6569 NSSLOWKEYRSAKey };
6570
6571 /* convert to a low RSA public key */
6572 low_RSA_public_key.u.rsa = rsaBlapiPublicKey;
6573 rsa_public_key = &low_RSA_public_key;
6574
6575 memset(signature, 0, sizeof(signature));
6576 i = 1;
6577 while (isspace(buf[i])((*__ctype_b_loc ())[(int) ((buf[i]))] & (unsigned short int
) _ISspace)
|| buf[i] == '=') {
6578 i++;
6579 }
6580
6581 for (j = 0; isxdigit(buf[i])((*__ctype_b_loc ())[(int) ((buf[i]))] & (unsigned short int
) _ISxdigit)
&& j < sizeof signature; i += 2, j++) {
6582 hex_to_byteval(&buf[i], &signature[j]);
6583 }
6584
6585 signatureLength = j;
6586 fputs(buf, rsaresp);
6587
6588 shaOid = fips_hashOid(shaAlg);
6589
6590 /* Perform RSA verification with the RSA public key. */
6591 rv = RSA_HashCheckSign(shaOid,
6592 rsa_public_key,
6593 signature,
6594 signatureLength,
6595 sha,
6596 shaLength);
6597 if (rv == SECSuccess) {
6598 fputs("Result = P\n", rsaresp);
6599 } else {
6600 fputs("Result = F\n", rsaresp);
6601 }
6602 continue;
6603 }
6604 }
6605loser:
6606 fclose(rsareq);
6607 if (rsaBlapiPublicKey.modulus.data) { /* n */
6608 SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(&rsaBlapiPublicKey.modulus, PR_FALSE0);
6609 }
6610 if (rsaBlapiPublicKey.publicExponent.data) { /* e */
6611 SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(&rsaBlapiPublicKey.publicExponent, PR_FALSE0);
6612 }
6613}
6614
6615void
6616tls(char *reqfn)
6617{
6618 char buf[256]; /* holds one line from the input REQUEST file.
6619 * needs to be large enough to hold the longest
6620 * line "XSeed = <128 hex digits>\n".
6621 */
6622 unsigned char *pms = NULL((void*)0);
6623 int pms_len;
6624 unsigned char *master_secret = NULL((void*)0);
6625 unsigned char *key_block = NULL((void*)0);
6626 int key_block_len;
6627 unsigned char serverHello_random[SSL3_RANDOM_LENGTH32];
6628 unsigned char clientHello_random[SSL3_RANDOM_LENGTH32];
6629 unsigned char server_random[SSL3_RANDOM_LENGTH32];
6630 unsigned char client_random[SSL3_RANDOM_LENGTH32];
6631 FILE *tlsreq = NULL((void*)0); /* input stream from the REQUEST file */
6632 FILE *tlsresp; /* output stream to the RESPONSE file */
6633 unsigned int i, j;
6634 CK_SLOT_ID slotList[10];
6635 CK_SLOT_ID slotID;
6636 CK_ULONG slotListCount = sizeof(slotList) / sizeof(slotList[0]);
6637 CK_ULONG count;
6638 static const CK_C_INITIALIZE_ARGS pk11args = {
6639 NULL((void*)0), NULL((void*)0), NULL((void*)0), NULL((void*)0), CKF_LIBRARY_CANT_CREATE_OS_THREADS0x00000001UL,
6640 (void *)"flags=readOnly,noCertDB,noModDB", NULL((void*)0)
6641 };
6642 static CK_OBJECT_CLASS ck_secret = CKO_SECRET_KEY0x00000004UL;
6643 static CK_KEY_TYPE ck_generic = CKK_GENERIC_SECRET0x00000010UL;
6644 static CK_BBOOL ck_true = CK_TRUE1;
6645 static CK_ULONG one = 1;
6646 CK_ATTRIBUTE create_template[] = {
6647 { CKA_VALUE0x00000011UL, NULL((void*)0), 0 },
6648 { CKA_CLASS0x00000000UL, &ck_secret, sizeof(ck_secret) },
6649 { CKA_KEY_TYPE0x00000100UL, &ck_generic, sizeof(ck_generic) },
6650 { CKA_DERIVE0x0000010CUL, &ck_true, sizeof(ck_true) },
6651 };
6652 CK_ULONG create_template_count =
6653 sizeof(create_template) / sizeof(create_template[0]);
6654 CK_ATTRIBUTE derive_template[] = {
6655 { CKA_CLASS0x00000000UL, &ck_secret, sizeof(ck_secret) },
6656 { CKA_KEY_TYPE0x00000100UL, &ck_generic, sizeof(ck_generic) },
6657 { CKA_DERIVE0x0000010CUL, &ck_true, sizeof(ck_true) },
6658 { CKA_VALUE_LEN0x00000161UL, &one, sizeof(one) },
6659 };
6660 CK_ULONG derive_template_count =
6661 sizeof(derive_template) / sizeof(derive_template[0]);
6662 CK_ATTRIBUTE master_template = { CKA_VALUE0x00000011UL, NULL((void*)0), 0 };
6663 CK_ATTRIBUTE kb1_template = { CKA_VALUE0x00000011UL, NULL((void*)0), 0 };
6664 CK_ATTRIBUTE kb2_template = { CKA_VALUE0x00000011UL, NULL((void*)0), 0 };
6665
6666 CK_MECHANISM master_mech = { CKM_TLS_MASTER_KEY_DERIVE0x00000375UL, NULL((void*)0), 0 };
6667 CK_MECHANISM key_block_mech = { CKM_TLS_KEY_AND_MAC_DERIVE0x00000376UL, NULL((void*)0), 0 };
6668 CK_TLS12_MASTER_KEY_DERIVE_PARAMS master_params;
6669 CK_TLS12_KEY_MAT_PARAMS key_block_params;
6670 CK_SSL3_KEY_MAT_OUT key_material;
6671 CK_RV crv;
6672
6673 /* set up PKCS #11 parameters */
6674 master_params.prfHashMechanism = CKM_SHA2560x00000250UL;
6675 master_params.pVersion = NULL((void*)0);
6676 master_params.RandomInfo.pClientRandom = clientHello_random;
6677 master_params.RandomInfo.ulClientRandomLen = sizeof(clientHello_random);
6678 master_params.RandomInfo.pServerRandom = serverHello_random;
6679 master_params.RandomInfo.ulServerRandomLen = sizeof(serverHello_random);
6680 master_mech.pParameter = (void *)&master_params;
6681 master_mech.ulParameterLen = sizeof(master_params);
6682 key_block_params.prfHashMechanism = CKM_SHA2560x00000250UL;
6683 key_block_params.ulMacSizeInBits = 0;
6684 key_block_params.ulKeySizeInBits = 0;
6685 key_block_params.ulIVSizeInBits = 0;
6686 key_block_params.bIsExport = PR_FALSE0; /* ignored anyway for TLS mech */
6687 key_block_params.RandomInfo.pClientRandom = client_random;
6688 key_block_params.RandomInfo.ulClientRandomLen = sizeof(client_random);
6689 key_block_params.RandomInfo.pServerRandom = server_random;
6690 key_block_params.RandomInfo.ulServerRandomLen = sizeof(server_random);
6691 key_block_params.pReturnedKeyMaterial = &key_material;
6692 key_block_mech.pParameter = (void *)&key_block_params;
6693 key_block_mech.ulParameterLen = sizeof(key_block_params);
6694
6695 crv = NSC_Initialize((CK_VOID_PTR)&pk11args);
6696 if (crv != CKR_OK0x00000000UL) {
6697 fprintf(stderrstderr, "NSC_Initialize failed crv=0x%x\n", (unsigned int)crv);
6698 goto loser;
6699 }
6700 count = slotListCount;
6701 crv = NSC_GetSlotList(PR_TRUE1, slotList, &count);
6702 if (crv != CKR_OK0x00000000UL) {
6703 fprintf(stderrstderr, "NSC_GetSlotList failed crv=0x%x\n", (unsigned int)crv);
6704 goto loser;
6705 }
6706 if ((count > slotListCount) || count < 1) {
6707 fprintf(stderrstderr,
6708 "NSC_GetSlotList returned too many or too few slots: %d slots max=%d min=1\n",
6709 (int)count, (int)slotListCount);
6710 goto loser;
6711 }
6712 slotID = slotList[0];
6713 tlsreq = fopen(reqfn, "r");
6714 tlsresp = stdoutstdout;
6715 while (fgets(buf, sizeof buf, tlsreq) != NULL((void*)0)) {
6716 /* a comment or blank line */
6717 if (buf[0] == '#' || buf[0] == '\n') {
6718 fputs(buf, tlsresp);
6719 continue;
6720 }
6721 /* [Xchange - SHA1] */
6722 if (buf[0] == '[') {
6723 if (strncmp(buf, "[TLS", 4) == 0) {
6724 if (buf[7] == '0') {
6725 /* CK_SSL3_MASTER_KEY_DERIVE_PARAMS is a subset of
6726 * CK_TLS12_MASTER_KEY_DERIVE_PARAMS and
6727 * CK_SSL3_KEY_MAT_PARAMS is a subset of
6728 * CK_TLS12_KEY_MAT_PARAMS. The latter params have
6729 * an extra prfHashMechanism field at the end. */
6730 master_mech.mechanism = CKM_TLS_MASTER_KEY_DERIVE0x00000375UL;
6731 key_block_mech.mechanism = CKM_TLS_KEY_AND_MAC_DERIVE0x00000376UL;
6732 master_mech.ulParameterLen = sizeof(CK_SSL3_MASTER_KEY_DERIVE_PARAMS);
6733 key_block_mech.ulParameterLen = sizeof(CK_SSL3_KEY_MAT_PARAMS);
6734 } else if (buf[7] == '2') {
6735 if (strncmp(&buf[10], "SHA-1", 5) == 0) {
6736 master_params.prfHashMechanism = CKM_SHA_10x00000220UL;
6737 key_block_params.prfHashMechanism = CKM_SHA_10x00000220UL;
6738 } else if (strncmp(&buf[10], "SHA-224", 7) == 0) {
6739 master_params.prfHashMechanism = CKM_SHA2240x00000255UL;
6740 key_block_params.prfHashMechanism = CKM_SHA2240x00000255UL;
6741 } else if (strncmp(&buf[10], "SHA-256", 7) == 0) {
6742 master_params.prfHashMechanism = CKM_SHA2560x00000250UL;
6743 key_block_params.prfHashMechanism = CKM_SHA2560x00000250UL;
6744 } else if (strncmp(&buf[10], "SHA-384", 7) == 0) {
6745 master_params.prfHashMechanism = CKM_SHA3840x00000260UL;
6746 key_block_params.prfHashMechanism = CKM_SHA3840x00000260UL;
6747 } else if (strncmp(&buf[10], "SHA-512", 7) == 0) {
6748 master_params.prfHashMechanism = CKM_SHA5120x00000270UL;
6749 key_block_params.prfHashMechanism = CKM_SHA5120x00000270UL;
6750 } else {
6751 fprintf(tlsresp, "ERROR: Unable to find prf Hash type");
6752 goto loser;
6753 }
6754 master_mech.mechanism = CKM_TLS12_MASTER_KEY_DERIVE0x000003E0UL;
6755 key_block_mech.mechanism = CKM_TLS12_KEY_AND_MAC_DERIVE0x000003E1UL;
6756 master_mech.ulParameterLen = sizeof(master_params);
6757 key_block_mech.ulParameterLen = sizeof(key_block_params);
6758 } else {
6759 fprintf(stderrstderr, "Unknown TLS type %x\n",
6760 (unsigned int)buf[0]);
6761 goto loser;
6762 }
6763 }
6764 if (strncmp(buf, "[pre-master", 11) == 0) {
6765 if (sscanf(buf, "[pre-master secret length = %d]",
6766 &pms_len) != 1) {
6767 goto loser;
6768 }
6769 pms_len = pms_len / 8;
6770 pms = malloc(pms_len);
6771 master_secret = malloc(pms_len);
6772 create_template[0].pValue = pms;
6773 create_template[0].ulValueLen = pms_len;
6774 master_template.pValue = master_secret;
6775 master_template.ulValueLen = pms_len;
6776 }
6777 if (strncmp(buf, "[key", 4) == 0) {
6778 if (sscanf(buf, "[key block length = %d]", &key_block_len) != 1) {
6779 goto loser;
6780 }
6781 key_block_params.ulKeySizeInBits = 8;
6782 key_block_params.ulIVSizeInBits = key_block_len / 2 - 8;
6783 key_block_len = key_block_len / 8;
6784 key_block = malloc(key_block_len);
6785 kb1_template.pValue = &key_block[0];
6786 kb1_template.ulValueLen = 1;
6787 kb2_template.pValue = &key_block[1];
6788 kb2_template.ulValueLen = 1;
6789 key_material.pIVClient = &key_block[2];
6790 key_material.pIVServer = &key_block[2 + key_block_len / 2 - 1];
6791 }
6792 fputs(buf, tlsresp);
6793 continue;
6794 }
6795 /* "COUNT = x" begins a new data set */
6796 if (strncmp(buf, "COUNT", 5) == 0) {
6797 /* zeroize the variables for the test with this data set */
6798 memset(pms, 0, pms_len);
6799 memset(master_secret, 0, pms_len);
6800 memset(key_block, 0, key_block_len);
6801 fputs(buf, tlsresp);
6802 continue;
6803 }
6804 /* pre_master_secret = ... */
6805 if (strncmp(buf, "pre_master_secret", 17) == 0) {
6806 i = 17;
6807 while (isspace(buf[i])((*__ctype_b_loc ())[(int) ((buf[i]))] & (unsigned short int
) _ISspace)
|| buf[i] == '=') {
6808 i++;
6809 }
6810 for (j = 0; j < pms_len; i += 2, j++) {
6811 hex_to_byteval(&buf[i], &pms[j]);
6812 }
6813 fputs(buf, tlsresp);
6814 continue;
6815 }
6816 /* serverHello_random = ... */
6817 if (strncmp(buf, "serverHello_random", 18) == 0) {
6818 i = 18;
6819 while (isspace(buf[i])((*__ctype_b_loc ())[(int) ((buf[i]))] & (unsigned short int
) _ISspace)
|| buf[i] == '=') {
6820 i++;
6821 }
6822 for (j = 0; j < SSL3_RANDOM_LENGTH32; i += 2, j++) {
6823 hex_to_byteval(&buf[i], &serverHello_random[j]);
6824 }
6825 fputs(buf, tlsresp);
6826 continue;
6827 }
6828 /* clientHello_random = ... */
6829 if (strncmp(buf, "clientHello_random", 18) == 0) {
6830 i = 18;
6831 while (isspace(buf[i])((*__ctype_b_loc ())[(int) ((buf[i]))] & (unsigned short int
) _ISspace)
|| buf[i] == '=') {
6832 i++;
6833 }
6834 for (j = 0; j < SSL3_RANDOM_LENGTH32; i += 2, j++) {
6835 hex_to_byteval(&buf[i], &clientHello_random[j]);
6836 }
6837 fputs(buf, tlsresp);
6838 continue;
6839 }
6840 /* server_random = ... */
6841 if (strncmp(buf, "server_random", 13) == 0) {
6842 i = 13;
6843 while (isspace(buf[i])((*__ctype_b_loc ())[(int) ((buf[i]))] & (unsigned short int
) _ISspace)
|| buf[i] == '=') {
6844 i++;
6845 }
6846 for (j = 0; j < SSL3_RANDOM_LENGTH32; i += 2, j++) {
6847 hex_to_byteval(&buf[i], &server_random[j]);
6848 }
6849 fputs(buf, tlsresp);
6850 continue;
6851 }
6852 /* client_random = ... */
6853 if (strncmp(buf, "client_random", 13) == 0) {
6854 CK_SESSION_HANDLE session;
6855 CK_OBJECT_HANDLE pms_handle;
6856 CK_OBJECT_HANDLE master_handle;
6857 CK_OBJECT_HANDLE fake_handle;
6858 i = 13;
6859 while (isspace(buf[i])((*__ctype_b_loc ())[(int) ((buf[i]))] & (unsigned short int
) _ISspace)
|| buf[i] == '=') {
6860 i++;
6861 }
6862 for (j = 0; j < SSL3_RANDOM_LENGTH32; i += 2, j++) {
6863 hex_to_byteval(&buf[i], &client_random[j]);
6864 }
6865 fputs(buf, tlsresp);
6866 crv = NSC_OpenSession(slotID, 0, NULL((void*)0), NULL((void*)0), &session);
6867 if (crv != CKR_OK0x00000000UL) {
6868 fprintf(stderrstderr, "NSC_OpenSession failed crv=0x%x\n",
6869 (unsigned int)crv);
6870 goto loser;
6871 }
6872 crv = NSC_CreateObject(session, create_template,
6873 create_template_count, &pms_handle);
6874 if (crv != CKR_OK0x00000000UL) {
6875 fprintf(stderrstderr, "NSC_CreateObject failed crv=0x%x\n",
6876 (unsigned int)crv);
6877 goto loser;
6878 }
6879 crv = NSC_DeriveKey(session, &master_mech, pms_handle,
6880 derive_template, derive_template_count - 1,
6881 &master_handle);
6882 if (crv != CKR_OK0x00000000UL) {
6883 fprintf(stderrstderr, "NSC_DeriveKey(master) failed crv=0x%x\n",
6884 (unsigned int)crv);
6885 goto loser;
6886 }
6887 crv = NSC_GetAttributeValue(session, master_handle,
6888 &master_template, 1);
6889 if (crv != CKR_OK0x00000000UL) {
6890 fprintf(stderrstderr, "NSC_GetAttribute failed crv=0x%x\n",
6891 (unsigned int)crv);
6892 goto loser;
6893 }
6894 fputs("master_secret = ", tlsresp);
6895 to_hex_str(buf, master_secret, pms_len);
6896 fputs(buf, tlsresp);
6897 fputc('\n', tlsresp);
6898 crv = NSC_DeriveKey(session, &key_block_mech, master_handle,
6899 derive_template, derive_template_count, &fake_handle);
6900 if (crv != CKR_OK0x00000000UL) {
6901 fprintf(stderrstderr,
6902 "NSC_DeriveKey(keyblock) failed crv=0x%x\n",
6903 (unsigned int)crv);
6904 goto loser;
6905 }
6906 crv = NSC_GetAttributeValue(session, key_material.hClientKey,
6907 &kb1_template, 1);
6908 if (crv != CKR_OK0x00000000UL) {
6909 fprintf(stderrstderr, "NSC_GetAttribute failed crv=0x%x\n",
6910 (unsigned int)crv);
6911 goto loser;
6912 }
6913 crv = NSC_GetAttributeValue(session, key_material.hServerKey,
6914 &kb2_template, 1);
6915 if (crv != CKR_OK0x00000000UL) {
6916 fprintf(stderrstderr, "NSC_GetAttribute failed crv=0x%x\n",
6917 (unsigned int)crv);
6918 goto loser;
6919 }
6920 fputs("key_block = ", tlsresp);
6921 to_hex_str(buf, key_block, key_block_len);
6922 fputs(buf, tlsresp);
6923 fputc('\n', tlsresp);
6924 crv = NSC_CloseSession(session);
6925 continue;
6926 }
6927 }
6928loser:
6929 NSC_Finalize(NULL((void*)0));
6930 if (pms)
6931 free(pms);
6932 if (master_secret)
6933 free(master_secret);
6934 if (key_block)
6935 free(key_block);
6936 if (tlsreq)
6937 fclose(tlsreq);
6938}
6939
6940void
6941ikev1(char *reqfn)
6942{
6943 char buf[4096]; /* holds one line from the input REQUEST file.
6944 * needs to be large enough to hold the longest
6945 * line "g^xy = <2048 hex digits>\n".
6946 */
6947 unsigned char *gxy = NULL((void*)0);
6948 int gxy_len;
6949 unsigned char *Ni = NULL((void*)0);
6950 int Ni_len;
6951 unsigned char *Nr = NULL((void*)0);
6952 int Nr_len;
6953 unsigned char CKYi[8];
6954 int CKYi_len;
6955 unsigned char CKYr[8];
6956 int CKYr_len;
6957 unsigned int i, j;
6958 FILE *ikereq = NULL((void*)0); /* input stream from the REQUEST file */
6959 FILE *ikeresp; /* output stream to the RESPONSE file */
6960
6961 CK_SLOT_ID slotList[10];
6962 CK_SLOT_ID slotID;
6963 CK_ULONG slotListCount = sizeof(slotList) / sizeof(slotList[0]);
6964 CK_ULONG count;
6965 static const CK_C_INITIALIZE_ARGS pk11args = {
6966 NULL((void*)0), NULL((void*)0), NULL((void*)0), NULL((void*)0), CKF_LIBRARY_CANT_CREATE_OS_THREADS0x00000001UL,
6967 (void *)"flags=readOnly,noCertDB,noModDB", NULL((void*)0)
6968 };
6969 static CK_OBJECT_CLASS ck_secret = CKO_SECRET_KEY0x00000004UL;
6970 static CK_KEY_TYPE ck_generic = CKK_GENERIC_SECRET0x00000010UL;
6971 static CK_BBOOL ck_true = CK_TRUE1;
6972 static CK_ULONG keyLen = 1;
6973 CK_ATTRIBUTE gxy_template[] = {
6974 { CKA_VALUE0x00000011UL, NULL((void*)0), 0 }, /* must be first */
6975 { CKA_CLASS0x00000000UL, &ck_secret, sizeof(ck_secret) },
6976 { CKA_KEY_TYPE0x00000100UL, &ck_generic, sizeof(ck_generic) },
6977 { CKA_DERIVE0x0000010CUL, &ck_true, sizeof(ck_true) },
6978 };
6979 CK_ULONG gxy_template_count =
6980 sizeof(gxy_template) / sizeof(gxy_template[0]);
6981 CK_ATTRIBUTE derive_template[] = {
6982 { CKA_CLASS0x00000000UL, &ck_secret, sizeof(ck_secret) },
6983 { CKA_KEY_TYPE0x00000100UL, &ck_generic, sizeof(ck_generic) },
6984 { CKA_DERIVE0x0000010CUL, &ck_true, sizeof(ck_true) },
6985 { CKA_VALUE_LEN0x00000161UL, &keyLen, sizeof(keyLen) }, /* must be last */
6986 };
6987 CK_ULONG derive_template_count =
6988 sizeof(derive_template) / sizeof(derive_template[0]);
6989 CK_ATTRIBUTE skeyid_template = { CKA_VALUE0x00000011UL, NULL((void*)0), 0 };
6990 CK_ATTRIBUTE skeyid_d_template = { CKA_VALUE0x00000011UL, NULL((void*)0), 0 };
6991 CK_ATTRIBUTE skeyid_a_template = { CKA_VALUE0x00000011UL, NULL((void*)0), 0 };
6992 CK_ATTRIBUTE skeyid_e_template = { CKA_VALUE0x00000011UL, NULL((void*)0), 0 };
6993 unsigned char skeyid_secret[HASH_LENGTH_MAX64];
6994 unsigned char skeyid_d_secret[HASH_LENGTH_MAX64];
6995 unsigned char skeyid_a_secret[HASH_LENGTH_MAX64];
6996 unsigned char skeyid_e_secret[HASH_LENGTH_MAX64];
6997
6998 CK_MECHANISM ike_mech = { CKM_NSS_IKE_PRF_DERIVE((0x80000000UL | 0x4E534350) + 35), NULL((void*)0), 0 };
6999 CK_MECHANISM ike1_mech = { CKM_NSS_IKE1_PRF_DERIVE((0x80000000UL | 0x4E534350) + 36), NULL((void*)0), 0 };
7000 CK_NSS_IKE_PRF_DERIVE_PARAMS ike_prf;
7001 CK_NSS_IKE1_PRF_DERIVE_PARAMS ike1_prf;
7002 CK_RV crv;
7003
7004 /* set up PKCS #11 parameters */
7005 ike_prf.bDataAsKey = PR_TRUE1;
7006 ike_prf.bRekey = PR_FALSE0;
7007 ike_prf.hNewKey = CK_INVALID_HANDLE0;
7008 CKYi_len = sizeof(CKYi);
7009 CKYr_len = sizeof(CKYr);
7010 ike1_prf.pCKYi = CKYi;
7011 ike1_prf.ulCKYiLen = CKYi_len;
7012 ike1_prf.pCKYr = CKYr;
7013 ike1_prf.ulCKYrLen = CKYr_len;
7014 ike_mech.pParameter = &ike_prf;
7015 ike_mech.ulParameterLen = sizeof(ike_prf);
7016 ike1_mech.pParameter = &ike1_prf;
7017 ike1_mech.ulParameterLen = sizeof(ike1_prf);
7018 skeyid_template.pValue = skeyid_secret;
7019 skeyid_template.ulValueLen = HASH_LENGTH_MAX64;
7020 skeyid_d_template.pValue = skeyid_d_secret;
7021 skeyid_d_template.ulValueLen = HASH_LENGTH_MAX64;
7022 skeyid_a_template.pValue = skeyid_a_secret;
7023 skeyid_a_template.ulValueLen = HASH_LENGTH_MAX64;
7024 skeyid_e_template.pValue = skeyid_e_secret;
7025 skeyid_e_template.ulValueLen = HASH_LENGTH_MAX64;
7026
7027 crv = NSC_Initialize((CK_VOID_PTR)&pk11args);
7028 if (crv != CKR_OK0x00000000UL) {
7029 fprintf(stderrstderr, "NSC_Initialize failed crv=0x%x\n", (unsigned int)crv);
7030 goto loser;
7031 }
7032 count = slotListCount;
7033 crv = NSC_GetSlotList(PR_TRUE1, slotList, &count);
7034 if (crv != CKR_OK0x00000000UL) {
7035 fprintf(stderrstderr, "NSC_GetSlotList failed crv=0x%x\n", (unsigned int)crv);
7036 goto loser;
7037 }
7038 if ((count > slotListCount) || count < 1) {
7039 fprintf(stderrstderr,
7040 "NSC_GetSlotList returned too many or too few slots: %d slots max=%d min=1\n",
7041 (int)count, (int)slotListCount);
7042 goto loser;
7043 }
7044 slotID = slotList[0];
7045 ikereq = fopen(reqfn, "r");
7046 ikeresp = stdoutstdout;
7047 while (fgets(buf, sizeof buf, ikereq) != NULL((void*)0)) {
7048 /* a comment or blank line */
7049 if (buf[0] == '#' || buf[0] == '\n') {
7050 fputs(buf, ikeresp);
7051 continue;
7052 }
7053 /* [.....] */
7054 if (buf[0] == '[') {
7055 if (strncmp(buf, "[SHA-1]", 7) == 0) {
7056 ike_prf.prfMechanism = CKM_SHA_1_HMAC0x00000221UL;
7057 ike1_prf.prfMechanism = CKM_SHA_1_HMAC0x00000221UL;
7058 }
7059 if (strncmp(buf, "[SHA-224]", 9) == 0) {
7060 ike_prf.prfMechanism = CKM_SHA224_HMAC0x00000256UL;
7061 ike1_prf.prfMechanism = CKM_SHA224_HMAC0x00000256UL;
7062 }
7063 if (strncmp(buf, "[SHA-256]", 9) == 0) {
7064 ike_prf.prfMechanism = CKM_SHA256_HMAC0x00000251UL;
7065 ike1_prf.prfMechanism = CKM_SHA256_HMAC0x00000251UL;
7066 }
7067 if (strncmp(buf, "[SHA-384]", 9) == 0) {
7068 ike_prf.prfMechanism = CKM_SHA384_HMAC0x00000261UL;
7069 ike1_prf.prfMechanism = CKM_SHA384_HMAC0x00000261UL;
7070 }
7071 if (strncmp(buf, "[SHA-512]", 9) == 0) {
7072 ike_prf.prfMechanism = CKM_SHA512_HMAC0x00000271UL;
7073 ike1_prf.prfMechanism = CKM_SHA512_HMAC0x00000271UL;
7074 }
7075 if (strncmp(buf, "[AES-XCBC", 9) == 0) {
7076 ike_prf.prfMechanism = CKM_AES_XCBC_MAC0x0000108CUL;
7077 ike1_prf.prfMechanism = CKM_AES_XCBC_MAC0x0000108CUL;
7078 }
7079 if (strncmp(buf, "[g^xy", 5) == 0) {
7080 if (sscanf(buf, "[g^xy length = %d]",
7081 &gxy_len) != 1) {
7082 goto loser;
7083 }
7084 gxy_len = gxy_len / 8;
7085 if (gxy)
7086 free(gxy);
7087 gxy = malloc(gxy_len);
7088 gxy_template[0].pValue = gxy;
7089 gxy_template[0].ulValueLen = gxy_len;
7090 }
7091 if (strncmp(buf, "[Ni", 3) == 0) {
7092 if (sscanf(buf, "[Ni length = %d]", &Ni_len) != 1) {
7093 goto loser;
7094 }
7095 Ni_len = Ni_len / 8;
7096 if (Ni)
7097 free(Ni);
7098 Ni = malloc(Ni_len);
7099 ike_prf.pNi = Ni;
7100 ike_prf.ulNiLen = Ni_len;
7101 }
7102 if (strncmp(buf, "[Nr", 3) == 0) {
7103 if (sscanf(buf, "[Nr length = %d]", &Nr_len) != 1) {
7104 goto loser;
7105 }
7106 Nr_len = Nr_len / 8;
7107 if (Nr)
7108 free(Nr);
7109 Nr = malloc(Nr_len);
7110 ike_prf.pNr = Nr;
7111 ike_prf.ulNrLen = Nr_len;
7112 }
7113 fputs(buf, ikeresp);
7114 continue;
7115 }
7116 /* "COUNT = x" begins a new data set */
7117 if (strncmp(buf, "COUNT", 5) == 0) {
7118 /* zeroize the variables for the test with this data set */
7119 memset(gxy, 0, gxy_len);
7120 memset(Ni, 0, Ni_len);
7121 memset(Nr, 0, Nr_len);
7122 memset(CKYi, 0, CKYi_len);
7123 memset(CKYr, 0, CKYr_len);
7124 fputs(buf, ikeresp);
7125 continue;
7126 }
7127 /* Ni = ... */
7128 if (strncmp(buf, "Ni", 2) == 0) {
7129 i = 2;
7130 while (isspace(buf[i])((*__ctype_b_loc ())[(int) ((buf[i]))] & (unsigned short int
) _ISspace)
|| buf[i] == '=') {
7131 i++;
7132 }
7133 for (j = 0; j < Ni_len; i += 2, j++) {
7134 hex_to_byteval(&buf[i], &Ni[j]);
7135 }
7136 fputs(buf, ikeresp);
7137 continue;
7138 }
7139 /* Nr = ... */
7140 if (strncmp(buf, "Nr", 2) == 0) {
7141 i = 2;
7142 while (isspace(buf[i])((*__ctype_b_loc ())[(int) ((buf[i]))] & (unsigned short int
) _ISspace)
|| buf[i] == '=') {
7143 i++;
7144 }
7145 for (j = 0; j < Nr_len; i += 2, j++) {
7146 hex_to_byteval(&buf[i], &Nr[j]);
7147 }
7148 fputs(buf, ikeresp);
7149 continue;
7150 }
7151 /* CKYi = ... */
7152 if (strncmp(buf, "CKY_I", 5) == 0) {
7153 i = 5;
7154 while (isspace(buf[i])((*__ctype_b_loc ())[(int) ((buf[i]))] & (unsigned short int
) _ISspace)
|| buf[i] == '=') {
7155 i++;
7156 }
7157 for (j = 0; j < CKYi_len; i += 2, j++) {
7158 hex_to_byteval(&buf[i], &CKYi[j]);
7159 }
7160 fputs(buf, ikeresp);
7161 continue;
7162 }
7163 /* CKYr = ... */
7164 if (strncmp(buf, "CKY_R", 5) == 0) {
7165 i = 5;
7166 while (isspace(buf[i])((*__ctype_b_loc ())[(int) ((buf[i]))] & (unsigned short int
) _ISspace)
|| buf[i] == '=') {
7167 i++;
7168 }
7169 for (j = 0; j < CKYr_len; i += 2, j++) {
7170 hex_to_byteval(&buf[i], &CKYr[j]);
7171 }
7172 fputs(buf, ikeresp);
7173 continue;
7174 }
7175 /* g^xy = ... */
7176 if (strncmp(buf, "g^xy", 4) == 0) {
7177 CK_SESSION_HANDLE session;
7178 CK_OBJECT_HANDLE gxy_handle;
7179 CK_OBJECT_HANDLE skeyid_handle;
7180 CK_OBJECT_HANDLE skeyid_d_handle;
7181 CK_OBJECT_HANDLE skeyid_a_handle;
7182 CK_OBJECT_HANDLE skeyid_e_handle;
7183 i = 4;
7184 while (isspace(buf[i])((*__ctype_b_loc ())[(int) ((buf[i]))] & (unsigned short int
) _ISspace)
|| buf[i] == '=') {
7185 i++;
7186 }
7187 for (j = 0; j < gxy_len; i += 2, j++) {
7188 hex_to_byteval(&buf[i], &gxy[j]);
7189 }
7190 fputs(buf, ikeresp);
7191 crv = NSC_OpenSession(slotID, 0, NULL((void*)0), NULL((void*)0), &session);
7192 if (crv != CKR_OK0x00000000UL) {
7193 fprintf(stderrstderr, "NSC_OpenSession failed crv=0x%x\n",
7194 (unsigned int)crv);
7195 goto loser;
7196 }
7197 crv = NSC_CreateObject(session, gxy_template,
7198 gxy_template_count, &gxy_handle);
7199 if (crv != CKR_OK0x00000000UL) {
7200 fprintf(stderrstderr, "NSC_CreateObject failed crv=0x%x\n",
7201 (unsigned int)crv);
7202 goto loser;
7203 }
7204 /* get the skeyid key */
7205 crv = NSC_DeriveKey(session, &ike_mech, gxy_handle,
7206 derive_template, derive_template_count - 1,
7207 &skeyid_handle);
7208 if (crv != CKR_OK0x00000000UL) {
7209 fprintf(stderrstderr, "NSC_DeriveKey(skeyid) failed crv=0x%x\n",
7210 (unsigned int)crv);
7211 goto loser;
7212 }
7213 skeyid_template.ulValueLen = HASH_LENGTH_MAX64;
7214 crv = NSC_GetAttributeValue(session, skeyid_handle,
7215 &skeyid_template, 1);
7216 if (crv != CKR_OK0x00000000UL) {
7217 fprintf(stderrstderr, "NSC_GetAttribute(skeyid) failed crv=0x%x\n",
7218 (unsigned int)crv);
7219 goto loser;
7220 }
7221 /* use the length of the skeyid to set the target length of all the
7222 * other keys */
7223 keyLen = skeyid_template.ulValueLen;
7224 ike1_prf.hKeygxy = gxy_handle;
7225 ike1_prf.bHasPrevKey = PR_FALSE0;
7226 ike1_prf.keyNumber = 0;
7227 crv = NSC_DeriveKey(session, &ike1_mech, skeyid_handle,
7228 derive_template, derive_template_count,
7229 &skeyid_d_handle);
7230 if (crv != CKR_OK0x00000000UL) {
7231 fprintf(stderrstderr, "NSC_DeriveKey(skeyid_d) failed crv=0x%x\n",
7232 (unsigned int)crv);
7233 goto loser;
7234 }
7235
7236 ike1_prf.hKeygxy = gxy_handle;
7237 ike1_prf.bHasPrevKey = CK_TRUE1;
7238 ike1_prf.hPrevKey = skeyid_d_handle;
7239 ike1_prf.keyNumber = 1;
7240 crv = NSC_DeriveKey(session, &ike1_mech, skeyid_handle,
7241 derive_template, derive_template_count,
7242 &skeyid_a_handle);
7243 if (crv != CKR_OK0x00000000UL) {
7244 fprintf(stderrstderr, "NSC_DeriveKey(skeyid_a) failed crv=0x%x\n",
7245 (unsigned int)crv);
7246 goto loser;
7247 }
7248 ike1_prf.hKeygxy = gxy_handle;
7249 ike1_prf.bHasPrevKey = CK_TRUE1;
7250 ike1_prf.hPrevKey = skeyid_a_handle;
7251 ike1_prf.keyNumber = 2;
7252 crv = NSC_DeriveKey(session, &ike1_mech, skeyid_handle,
7253 derive_template, derive_template_count,
7254 &skeyid_e_handle);
7255 if (crv != CKR_OK0x00000000UL) {
7256 fprintf(stderrstderr, "NSC_DeriveKey(skeyid_e) failed crv=0x%x\n",
7257 (unsigned int)crv);
7258 goto loser;
7259 }
7260 fputs("SKEYID = ", ikeresp);
7261 to_hex_str(buf, skeyid_secret, keyLen);
7262 fputs(buf, ikeresp);
7263 fputc('\n', ikeresp);
7264
7265 skeyid_d_template.ulValueLen = keyLen;
7266 crv = NSC_GetAttributeValue(session, skeyid_d_handle,
7267 &skeyid_d_template, 1);
7268 if (crv != CKR_OK0x00000000UL) {
7269 fprintf(stderrstderr, "NSC_GetAttribute(skeyid_d) failed crv=0x%x\n",
7270 (unsigned int)crv);
7271 goto loser;
7272 }
7273 fputs("SKEYID_d = ", ikeresp);
7274 to_hex_str(buf, skeyid_d_secret, skeyid_d_template.ulValueLen);
7275 fputs(buf, ikeresp);
7276 fputc('\n', ikeresp);
7277
7278 skeyid_a_template.ulValueLen = keyLen;
7279 crv = NSC_GetAttributeValue(session, skeyid_a_handle,
7280 &skeyid_a_template, 1);
7281 if (crv != CKR_OK0x00000000UL) {
7282 fprintf(stderrstderr, "NSC_GetAttribute(skeyid_a) failed crv=0x%x\n",
7283 (unsigned int)crv);
7284 goto loser;
7285 }
7286 fputs("SKEYID_a = ", ikeresp);
7287 to_hex_str(buf, skeyid_a_secret, skeyid_a_template.ulValueLen);
7288 fputs(buf, ikeresp);
7289 fputc('\n', ikeresp);
7290
7291 skeyid_e_template.ulValueLen = keyLen;
7292 crv = NSC_GetAttributeValue(session, skeyid_e_handle,
7293 &skeyid_e_template, 1);
7294 if (crv != CKR_OK0x00000000UL) {
7295 fprintf(stderrstderr, "NSC_GetAttribute(skeyid_e) failed crv=0x%x\n",
7296 (unsigned int)crv);
7297 goto loser;
7298 }
7299 fputs("SKEYID_e = ", ikeresp);
7300 to_hex_str(buf, skeyid_e_secret, skeyid_e_template.ulValueLen);
7301 fputs(buf, ikeresp);
7302 fputc('\n', ikeresp);
7303
7304 crv = NSC_CloseSession(session);
7305 continue;
7306 }
7307 }
7308loser:
7309 NSC_Finalize(NULL((void*)0));
7310 if (gxy)
7311 free(gxy);
7312 if (Ni)
7313 free(Ni);
7314 if (Nr)
7315 free(Nr);
7316 if (ikereq)
7317 fclose(ikereq);
7318}
7319
7320void
7321ikev1_psk(char *reqfn)
7322{
7323 char buf[4096]; /* holds one line from the input REQUEST file.
7324 * needs to be large enough to hold the longest
7325 * line "g^xy = <2048 hex digits>\n".
7326 */
7327 unsigned char *gxy = NULL((void*)0);
7328 int gxy_len;
7329 unsigned char *Ni = NULL((void*)0);
7330 int Ni_len;
7331 unsigned char *Nr = NULL((void*)0);
7332 int Nr_len;
7333 unsigned char CKYi[8];
7334 int CKYi_len;
7335 unsigned char CKYr[8];
7336 int CKYr_len;
7337 unsigned char *psk = NULL((void*)0);
7338 int psk_len;
1
'psk_len' declared without an initial value
7339 unsigned int i, j;
7340 FILE *ikereq = NULL((void*)0); /* input stream from the REQUEST file */
7341 FILE *ikeresp; /* output stream to the RESPONSE file */
7342
7343 CK_SLOT_ID slotList[10];
7344 CK_SLOT_ID slotID;
7345 CK_ULONG slotListCount = sizeof(slotList) / sizeof(slotList[0]);
7346 CK_ULONG count;
7347 static const CK_C_INITIALIZE_ARGS pk11args = {
7348 NULL((void*)0), NULL((void*)0), NULL((void*)0), NULL((void*)0), CKF_LIBRARY_CANT_CREATE_OS_THREADS0x00000001UL,
7349 (void *)"flags=readOnly,noCertDB,noModDB", NULL((void*)0)
7350 };
7351 static CK_OBJECT_CLASS ck_secret = CKO_SECRET_KEY0x00000004UL;
7352 static CK_KEY_TYPE ck_generic = CKK_GENERIC_SECRET0x00000010UL;
7353 static CK_BBOOL ck_true = CK_TRUE1;
7354 static CK_ULONG keyLen = 1;
7355 CK_ATTRIBUTE gxy_template[] = {
7356 { CKA_VALUE0x00000011UL, NULL((void*)0), 0 }, /* must be first */
7357 { CKA_CLASS0x00000000UL, &ck_secret, sizeof(ck_secret) },
7358 { CKA_KEY_TYPE0x00000100UL, &ck_generic, sizeof(ck_generic) },
7359 { CKA_DERIVE0x0000010CUL, &ck_true, sizeof(ck_true) },
7360 };
7361 CK_ULONG gxy_template_count =
7362 sizeof(gxy_template) / sizeof(gxy_template[0]);
7363 CK_ATTRIBUTE psk_template[] = {
7364 { CKA_VALUE0x00000011UL, NULL((void*)0), 0 }, /* must be first */
7365 { CKA_CLASS0x00000000UL, &ck_secret, sizeof(ck_secret) },
7366 { CKA_KEY_TYPE0x00000100UL, &ck_generic, sizeof(ck_generic) },
7367 { CKA_DERIVE0x0000010CUL, &ck_true, sizeof(ck_true) },
7368 };
7369 CK_ULONG psk_template_count =
7370 sizeof(psk_template) / sizeof(psk_template[0]);
7371 CK_ATTRIBUTE derive_template[] = {
7372 { CKA_CLASS0x00000000UL, &ck_secret, sizeof(ck_secret) },
7373 { CKA_KEY_TYPE0x00000100UL, &ck_generic, sizeof(ck_generic) },
7374 { CKA_DERIVE0x0000010CUL, &ck_true, sizeof(ck_true) },
7375 { CKA_VALUE_LEN0x00000161UL, &keyLen, sizeof(keyLen) }, /* must be last */
7376 };
7377 CK_ULONG derive_template_count =
7378 sizeof(derive_template) / sizeof(derive_template[0]);
7379 CK_ATTRIBUTE skeyid_template = { CKA_VALUE0x00000011UL, NULL((void*)0), 0 };
7380 CK_ATTRIBUTE skeyid_d_template = { CKA_VALUE0x00000011UL, NULL((void*)0), 0 };
7381 CK_ATTRIBUTE skeyid_a_template = { CKA_VALUE0x00000011UL, NULL((void*)0), 0 };
7382 CK_ATTRIBUTE skeyid_e_template = { CKA_VALUE0x00000011UL, NULL((void*)0), 0 };
7383 unsigned char skeyid_secret[HASH_LENGTH_MAX64];
7384 unsigned char skeyid_d_secret[HASH_LENGTH_MAX64];
7385 unsigned char skeyid_a_secret[HASH_LENGTH_MAX64];
7386 unsigned char skeyid_e_secret[HASH_LENGTH_MAX64];
7387
7388 CK_MECHANISM ike_mech = { CKM_NSS_IKE_PRF_DERIVE((0x80000000UL | 0x4E534350) + 35), NULL((void*)0), 0 };
7389 CK_MECHANISM ike1_mech = { CKM_NSS_IKE1_PRF_DERIVE((0x80000000UL | 0x4E534350) + 36), NULL((void*)0), 0 };
7390 CK_NSS_IKE_PRF_DERIVE_PARAMS ike_prf;
7391 CK_NSS_IKE1_PRF_DERIVE_PARAMS ike1_prf;
7392 CK_RV crv;
7393
7394 /* set up PKCS #11 parameters */
7395 ike_prf.bDataAsKey = PR_FALSE0;
7396 ike_prf.bRekey = PR_FALSE0;
7397 ike_prf.hNewKey = CK_INVALID_HANDLE0;
7398 CKYi_len = 8;
7399 CKYr_len = 8;
7400 ike1_prf.pCKYi = CKYi;
7401 ike1_prf.ulCKYiLen = CKYi_len;
7402 ike1_prf.pCKYr = CKYr;
7403 ike1_prf.ulCKYrLen = CKYr_len;
7404 ike_mech.pParameter = &ike_prf;
7405 ike_mech.ulParameterLen = sizeof(ike_prf);
7406 ike1_mech.pParameter = &ike1_prf;
7407 ike1_mech.ulParameterLen = sizeof(ike1_prf);
7408 skeyid_template.pValue = skeyid_secret;
7409 skeyid_template.ulValueLen = HASH_LENGTH_MAX64;
7410 skeyid_d_template.pValue = skeyid_d_secret;
7411 skeyid_d_template.ulValueLen = HASH_LENGTH_MAX64;
7412 skeyid_a_template.pValue = skeyid_a_secret;
7413 skeyid_a_template.ulValueLen = HASH_LENGTH_MAX64;
7414 skeyid_e_template.pValue = skeyid_e_secret;
7415 skeyid_e_template.ulValueLen = HASH_LENGTH_MAX64;
7416
7417 crv = NSC_Initialize((CK_VOID_PTR)&pk11args);
7418 if (crv != CKR_OK0x00000000UL) {
2
Assuming 'crv' is equal to CKR_OK
3
Taking false branch
7419 fprintf(stderrstderr, "NSC_Initialize failed crv=0x%x\n", (unsigned int)crv);
7420 goto loser;
7421 }
7422 count = slotListCount;
7423 crv = NSC_GetSlotList(PR_TRUE1, slotList, &count);
7424 if (crv != CKR_OK0x00000000UL) {
4
Assuming 'crv' is equal to CKR_OK
7425 fprintf(stderrstderr, "NSC_GetSlotList failed crv=0x%x\n", (unsigned int)crv);
7426 goto loser;
7427 }
7428 if ((count > slotListCount) || count < 1) {
5
Assuming 'count' is <= 'slotListCount'
6
Assuming 'count' is >= 1
7
Taking false branch
7429 fprintf(stderrstderr,
7430 "NSC_GetSlotList returned too many or too few slots: %d slots max=%d min=1\n",
7431 (int)count, (int)slotListCount);
7432 goto loser;
7433 }
7434 slotID = slotList[0];
7435 ikereq = fopen(reqfn, "r");
7436 ikeresp = stdoutstdout;
7437 while (fgets(buf, sizeof buf, ikereq) != NULL((void*)0)) {
8
Assuming the condition is true
7438 /* a comment or blank line */
7439 if (buf[0] == '#' || buf[0] == '\n') {
9
Assuming the condition is false
10
Assuming the condition is false
11
Taking false branch
7440 fputs(buf, ikeresp);
7441 continue;
7442 }
7443 /* [.....] */
7444 if (buf[0] == '[') {
12
Assuming the condition is false
13
Taking false branch
7445 if (strncmp(buf, "[SHA-1]", 7) == 0) {
7446 ike_prf.prfMechanism = CKM_SHA_1_HMAC0x00000221UL;
7447 ike1_prf.prfMechanism = CKM_SHA_1_HMAC0x00000221UL;
7448 }
7449 if (strncmp(buf, "[SHA-224]", 9) == 0) {
7450 ike_prf.prfMechanism = CKM_SHA224_HMAC0x00000256UL;
7451 ike1_prf.prfMechanism = CKM_SHA224_HMAC0x00000256UL;
7452 }
7453 if (strncmp(buf, "[SHA-256]", 9) == 0) {
7454 ike_prf.prfMechanism = CKM_SHA256_HMAC0x00000251UL;
7455 ike1_prf.prfMechanism = CKM_SHA256_HMAC0x00000251UL;
7456 }
7457 if (strncmp(buf, "[SHA-384]", 9) == 0) {
7458 ike_prf.prfMechanism = CKM_SHA384_HMAC0x00000261UL;
7459 ike1_prf.prfMechanism = CKM_SHA384_HMAC0x00000261UL;
7460 }
7461 if (strncmp(buf, "[SHA-512]", 9) == 0) {
7462 ike_prf.prfMechanism = CKM_SHA512_HMAC0x00000271UL;
7463 ike1_prf.prfMechanism = CKM_SHA512_HMAC0x00000271UL;
7464 }
7465 if (strncmp(buf, "[AES-XCBC", 9) == 0) {
7466 ike_prf.prfMechanism = CKM_AES_XCBC_MAC0x0000108CUL;
7467 ike1_prf.prfMechanism = CKM_AES_XCBC_MAC0x0000108CUL;
7468 }
7469 if (strncmp(buf, "[g^xy", 5) == 0) {
7470 if (sscanf(buf, "[g^xy length = %d]",
7471 &gxy_len) != 1) {
7472 goto loser;
7473 }
7474 gxy_len = gxy_len / 8;
7475 if (gxy)
7476 free(gxy);
7477 gxy = malloc(gxy_len);
7478 gxy_template[0].pValue = gxy;
7479 gxy_template[0].ulValueLen = gxy_len;
7480 }
7481 if (strncmp(buf, "[pre-shared-key", 15) == 0) {
7482 if (sscanf(buf, "[pre-shared-key length = %d]",
7483 &psk_len) != 1) {
7484 goto loser;
7485 }
7486 psk_len = psk_len / 8;
7487 if (psk)
7488 free(psk);
7489 psk = malloc(psk_len);
7490 psk_template[0].pValue = psk;
7491 psk_template[0].ulValueLen = psk_len;
7492 }
7493 if (strncmp(buf, "[Ni", 3) == 0) {
7494 if (sscanf(buf, "[Ni length = %d]", &Ni_len) != 1) {
7495 goto loser;
7496 }
7497 Ni_len = Ni_len / 8;
7498 if (Ni)
7499 free(Ni);
7500 Ni = malloc(Ni_len);
7501 ike_prf.pNi = Ni;
7502 ike_prf.ulNiLen = Ni_len;
7503 }
7504 if (strncmp(buf, "[Nr", 3) == 0) {
7505 if (sscanf(buf, "[Nr length = %d]", &Nr_len) != 1) {
7506 goto loser;
7507 }
7508 Nr_len = Nr_len / 8;
7509 if (Nr)
7510 free(Nr);
7511 Nr = malloc(Nr_len);
7512 ike_prf.pNr = Nr;
7513 ike_prf.ulNrLen = Nr_len;
7514 }
7515 fputs(buf, ikeresp);
7516 continue;
7517 }
7518 /* "COUNT = x" begins a new data set */
7519 if (strncmp(buf, "COUNT", 5) == 0) {
14
Assuming the condition is false
15
Taking false branch
7520 /* zeroize the variables for the test with this data set */
7521 memset(gxy, 0, gxy_len);
7522 memset(Ni, 0, Ni_len);
7523 memset(Nr, 0, Nr_len);
7524 memset(CKYi, 0, CKYi_len);
7525 memset(CKYr, 0, CKYr_len);
7526 fputs(buf, ikeresp);
7527 continue;
7528 }
7529 /* Ni = ... */
7530 if (strncmp(buf, "Ni", 2) == 0) {
16
Assuming the condition is false
17
Taking false branch
7531 i = 2;
7532 while (isspace(buf[i])((*__ctype_b_loc ())[(int) ((buf[i]))] & (unsigned short int
) _ISspace)
|| buf[i] == '=') {
7533 i++;
7534 }
7535 for (j = 0; j < Ni_len; i += 2, j++) {
7536 hex_to_byteval(&buf[i], &Ni[j]);
7537 }
7538 fputs(buf, ikeresp);
7539 continue;
7540 }
7541 /* Nr = ... */
7542 if (strncmp(buf, "Nr", 2) == 0) {
18
Assuming the condition is false
19
Taking false branch
7543 i = 2;
7544 while (isspace(buf[i])((*__ctype_b_loc ())[(int) ((buf[i]))] & (unsigned short int
) _ISspace)
|| buf[i] == '=') {
7545 i++;
7546 }
7547 for (j = 0; j < Nr_len; i += 2, j++) {
7548 hex_to_byteval(&buf[i], &Nr[j]);
7549 }
7550 fputs(buf, ikeresp);
7551 continue;
7552 }
7553 /* CKYi = ... */
7554 if (strncmp(buf, "CKY_I", 5) == 0) {
20
Assuming the condition is false
21
Taking false branch
7555 i = 5;
7556 while (isspace(buf[i])((*__ctype_b_loc ())[(int) ((buf[i]))] & (unsigned short int
) _ISspace)
|| buf[i] == '=') {
7557 i++;
7558 }
7559 for (j = 0; j < CKYi_len; i += 2, j++) {
7560 hex_to_byteval(&buf[i], &CKYi[j]);
7561 }
7562 fputs(buf, ikeresp);
7563 continue;
7564 }
7565 /* CKYr = ... */
7566 if (strncmp(buf, "CKY_R", 5) == 0) {
22
Assuming the condition is false
23
Taking false branch
7567 i = 5;
7568 while (isspace(buf[i])((*__ctype_b_loc ())[(int) ((buf[i]))] & (unsigned short int
) _ISspace)
|| buf[i] == '=') {
7569 i++;
7570 }
7571 for (j = 0; j < CKYr_len; i += 2, j++) {
7572 hex_to_byteval(&buf[i], &CKYr[j]);
7573 }
7574 fputs(buf, ikeresp);
7575 continue;
7576 }
7577 /* g^xy = ... */
7578 if (strncmp(buf, "g^xy", 4) == 0) {
24
Assuming the condition is false
25
Taking false branch
7579 i = 4;
7580 while (isspace(buf[i])((*__ctype_b_loc ())[(int) ((buf[i]))] & (unsigned short int
) _ISspace)
|| buf[i] == '=') {
7581 i++;
7582 }
7583 for (j = 0; j < gxy_len; i += 2, j++) {
7584 hex_to_byteval(&buf[i], &gxy[j]);
7585 }
7586 fputs(buf, ikeresp);
7587 continue;
7588 }
7589 /* pre-shared-key = ... */
7590 if (strncmp(buf, "pre-shared-key", 14) == 0) {
26
Assuming the condition is true
27
Taking true branch
7591 CK_SESSION_HANDLE session;
7592 CK_OBJECT_HANDLE gxy_handle;
7593 CK_OBJECT_HANDLE psk_handle;
7594 CK_OBJECT_HANDLE skeyid_handle;
7595 CK_OBJECT_HANDLE skeyid_d_handle;
7596 CK_OBJECT_HANDLE skeyid_a_handle;
7597 CK_OBJECT_HANDLE skeyid_e_handle;
7598 i = 14;
7599 while (isspace(buf[i])((*__ctype_b_loc ())[(int) ((buf[i]))] & (unsigned short int
) _ISspace)
|| buf[i] == '=') {
28
Assuming the condition is false
29
Assuming the condition is false
30
Loop condition is false. Execution continues on line 7602
7600 i++;
7601 }
7602 for (j = 0; j < psk_len; i += 2, j++) {
31
The right operand of '<' is a garbage value
7603 hex_to_byteval(&buf[i], &psk[j]);
7604 }
7605 fputs(buf, ikeresp);
7606 crv = NSC_OpenSession(slotID, 0, NULL((void*)0), NULL((void*)0), &session);
7607 if (crv != CKR_OK0x00000000UL) {
7608 fprintf(stderrstderr, "NSC_OpenSession failed crv=0x%x\n",
7609 (unsigned int)crv);
7610 goto loser;
7611 }
7612 crv = NSC_CreateObject(session, psk_template,
7613 psk_template_count, &psk_handle);
7614 if (crv != CKR_OK0x00000000UL) {
7615 fprintf(stderrstderr, "NSC_CreateObject(psk) failed crv=0x%x\n",
7616 (unsigned int)crv);
7617 goto loser;
7618 }
7619 crv = NSC_CreateObject(session, gxy_template,
7620 gxy_template_count, &gxy_handle);
7621 if (crv != CKR_OK0x00000000UL) {
7622 fprintf(stderrstderr, "NSC_CreateObject(gxy) failed crv=0x%x\n",
7623 (unsigned int)crv);
7624 goto loser;
7625 }
7626 /* get the skeyid key */
7627 crv = NSC_DeriveKey(session, &ike_mech, psk_handle,
7628 derive_template, derive_template_count - 1,
7629 &skeyid_handle);
7630 if (crv != CKR_OK0x00000000UL) {
7631 fprintf(stderrstderr, "NSC_DeriveKey(skeyid) failed crv=0x%x\n",
7632 (unsigned int)crv);
7633 goto loser;
7634 }
7635 skeyid_template.ulValueLen = HASH_LENGTH_MAX64;
7636 crv = NSC_GetAttributeValue(session, skeyid_handle,
7637 &skeyid_template, 1);
7638 if (crv != CKR_OK0x00000000UL) {
7639 fprintf(stderrstderr, "NSC_GetAttribute(skeyid) failed crv=0x%x\n",
7640 (unsigned int)crv);
7641 goto loser;
7642 }
7643 /* use the length of the skeyid to set the target length of all the
7644 * other keys */
7645 keyLen = skeyid_template.ulValueLen;
7646 ike1_prf.hKeygxy = gxy_handle;
7647 ike1_prf.bHasPrevKey = PR_FALSE0;
7648 ike1_prf.keyNumber = 0;
7649 crv = NSC_DeriveKey(session, &ike1_mech, skeyid_handle,
7650 derive_template, derive_template_count,
7651 &skeyid_d_handle);
7652 if (crv != CKR_OK0x00000000UL) {
7653 fprintf(stderrstderr, "NSC_DeriveKey(skeyid_d) failed crv=0x%x\n",
7654 (unsigned int)crv);
7655 goto loser;
7656 }
7657
7658 ike1_prf.hKeygxy = gxy_handle;
7659 ike1_prf.bHasPrevKey = CK_TRUE1;
7660 ike1_prf.hPrevKey = skeyid_d_handle;
7661 ike1_prf.keyNumber = 1;
7662 crv = NSC_DeriveKey(session, &ike1_mech, skeyid_handle,
7663 derive_template, derive_template_count,
7664 &skeyid_a_handle);
7665 if (crv != CKR_OK0x00000000UL) {
7666 fprintf(stderrstderr, "NSC_DeriveKey(skeyid_a) failed crv=0x%x\n",
7667 (unsigned int)crv);
7668 goto loser;
7669 }
7670 ike1_prf.hKeygxy = gxy_handle;
7671 ike1_prf.bHasPrevKey = CK_TRUE1;
7672 ike1_prf.hPrevKey = skeyid_a_handle;
7673 ike1_prf.keyNumber = 2;
7674 crv = NSC_DeriveKey(session, &ike1_mech, skeyid_handle,
7675 derive_template, derive_template_count,
7676 &skeyid_e_handle);
7677 if (crv != CKR_OK0x00000000UL) {
7678 fprintf(stderrstderr, "NSC_DeriveKey(skeyid_e) failed crv=0x%x\n",
7679 (unsigned int)crv);
7680 goto loser;
7681 }
7682 fputs("SKEYID = ", ikeresp);
7683 to_hex_str(buf, skeyid_secret, keyLen);
7684 fputs(buf, ikeresp);
7685 fputc('\n', ikeresp);
7686
7687 skeyid_d_template.ulValueLen = keyLen;
7688 crv = NSC_GetAttributeValue(session, skeyid_d_handle,
7689 &skeyid_d_template, 1);
7690 if (crv != CKR_OK0x00000000UL) {
7691 fprintf(stderrstderr, "NSC_GetAttribute(skeyid_d) failed crv=0x%x\n",
7692 (unsigned int)crv);
7693 goto loser;
7694 }
7695 fputs("SKEYID_d = ", ikeresp);
7696 to_hex_str(buf, skeyid_d_secret, skeyid_d_template.ulValueLen);
7697 fputs(buf, ikeresp);
7698 fputc('\n', ikeresp);
7699
7700 skeyid_a_template.ulValueLen = keyLen;
7701 crv = NSC_GetAttributeValue(session, skeyid_a_handle,
7702 &skeyid_a_template, 1);
7703 if (crv != CKR_OK0x00000000UL) {
7704 fprintf(stderrstderr, "NSC_GetAttribute(skeyid_a) failed crv=0x%x\n",
7705 (unsigned int)crv);
7706 goto loser;
7707 }
7708 fputs("SKEYID_a = ", ikeresp);
7709 to_hex_str(buf, skeyid_a_secret, skeyid_a_template.ulValueLen);
7710 fputs(buf, ikeresp);
7711 fputc('\n', ikeresp);
7712
7713 skeyid_e_template.ulValueLen = keyLen;
7714 crv = NSC_GetAttributeValue(session, skeyid_e_handle,
7715 &skeyid_e_template, 1);
7716 if (crv != CKR_OK0x00000000UL) {
7717 fprintf(stderrstderr, "NSC_GetAttribute(skeyid_e) failed crv=0x%x\n",
7718 (unsigned int)crv);
7719 goto loser;
7720 }
7721 fputs("SKEYID_e = ", ikeresp);
7722 to_hex_str(buf, skeyid_e_secret, skeyid_e_template.ulValueLen);
7723 fputs(buf, ikeresp);
7724 fputc('\n', ikeresp);
7725
7726 crv = NSC_CloseSession(session);
7727 continue;
7728 }
7729 }
7730loser:
7731 NSC_Finalize(NULL((void*)0));
7732 if (psk)
7733 free(psk);
7734 if (gxy)
7735 free(gxy);
7736 if (Ni)
7737 free(Ni);
7738 if (Nr)
7739 free(Nr);
7740 if (ikereq)
7741 fclose(ikereq);
7742}
7743
7744void
7745ikev2(char *reqfn)
7746{
7747 char buf[4096]; /* holds one line from the input REQUEST file.
7748 * needs to be large enough to hold the longest
7749 * line "g^xy = <2048 hex digits>\n".
7750 */
7751 unsigned char *gir = NULL((void*)0);
7752 unsigned char *gir_new = NULL((void*)0);
7753 int gir_len;
7754 unsigned char *Ni = NULL((void*)0);
7755 int Ni_len;
7756 unsigned char *Nr = NULL((void*)0);
7757 int Nr_len;
7758 unsigned char *SPIi = NULL((void*)0);
7759 int SPIi_len = 8;
7760 unsigned char *SPIr = NULL((void*)0);
7761 int SPIr_len = 8;
7762 unsigned char *DKM = NULL((void*)0);
7763 int DKM_len;
7764 unsigned char *DKM_child = NULL((void*)0);
7765 int DKM_child_len;
7766 unsigned char *seed_data = NULL((void*)0);
7767 int seed_data_len = 0;
7768 unsigned int i, j;
7769 FILE *ikereq = NULL((void*)0); /* input stream from the REQUEST file */
7770 FILE *ikeresp; /* output stream to the RESPONSE file */
7771
7772 CK_SLOT_ID slotList[10];
7773 CK_SLOT_ID slotID;
7774 CK_ULONG slotListCount = sizeof(slotList) / sizeof(slotList[0]);
7775 CK_ULONG count;
7776 static const CK_C_INITIALIZE_ARGS pk11args = {
7777 NULL((void*)0), NULL((void*)0), NULL((void*)0), NULL((void*)0), CKF_LIBRARY_CANT_CREATE_OS_THREADS0x00000001UL,
7778 (void *)"flags=readOnly,noCertDB,noModDB", NULL((void*)0)
7779 };
7780 static CK_OBJECT_CLASS ck_secret = CKO_SECRET_KEY0x00000004UL;
7781 static CK_KEY_TYPE ck_generic = CKK_GENERIC_SECRET0x00000010UL;
7782 static CK_BBOOL ck_true = CK_TRUE1;
7783 static CK_ULONG keyLen = 1;
7784 CK_ATTRIBUTE gir_template[] = {
7785 { CKA_VALUE0x00000011UL, NULL((void*)0), 0 },
7786 { CKA_CLASS0x00000000UL, &ck_secret, sizeof(ck_secret) },
7787 { CKA_KEY_TYPE0x00000100UL, &ck_generic, sizeof(ck_generic) },
7788 { CKA_DERIVE0x0000010CUL, &ck_true, sizeof(ck_true) },
7789 };
7790 CK_ULONG gir_template_count =
7791 sizeof(gir_template) / sizeof(gir_template[0]);
7792 CK_ATTRIBUTE gir_new_template[] = {
7793 { CKA_VALUE0x00000011UL, NULL((void*)0), 0 },
7794 { CKA_CLASS0x00000000UL, &ck_secret, sizeof(ck_secret) },
7795 { CKA_KEY_TYPE0x00000100UL, &ck_generic, sizeof(ck_generic) },
7796 { CKA_DERIVE0x0000010CUL, &ck_true, sizeof(ck_true) },
7797 };
7798 CK_ULONG gir_new_template_count =
7799 sizeof(gir_new_template) / sizeof(gir_new_template[0]);
7800 CK_ATTRIBUTE derive_template[] = {
7801 { CKA_CLASS0x00000000UL, &ck_secret, sizeof(ck_secret) },
7802 { CKA_KEY_TYPE0x00000100UL, &ck_generic, sizeof(ck_generic) },
7803 { CKA_DERIVE0x0000010CUL, &ck_true, sizeof(ck_true) },
7804 { CKA_VALUE_LEN0x00000161UL, &keyLen, sizeof(keyLen) },
7805 };
7806 CK_ULONG derive_template_count =
7807 sizeof(derive_template) / sizeof(derive_template[0]);
7808 CK_ATTRIBUTE skeyseed_template = { CKA_VALUE0x00000011UL, NULL((void*)0), 0 };
7809 CK_ATTRIBUTE dkm_template = { CKA_VALUE0x00000011UL, NULL((void*)0), 0 };
7810 CK_ATTRIBUTE dkm_child_template = { CKA_VALUE0x00000011UL, NULL((void*)0), 0 };
7811 unsigned char skeyseed_secret[HASH_LENGTH_MAX64];
7812
7813 CK_MECHANISM ike_mech = { CKM_NSS_IKE_PRF_DERIVE((0x80000000UL | 0x4E534350) + 35), NULL((void*)0), 0 };
7814 CK_MECHANISM ike2_mech = { CKM_NSS_IKE_PRF_PLUS_DERIVE((0x80000000UL | 0x4E534350) + 34), NULL((void*)0), 0 };
7815 CK_MECHANISM subset_mech = { CKM_EXTRACT_KEY_FROM_KEY0x00000365UL, NULL((void*)0), 0 };
7816 CK_NSS_IKE_PRF_DERIVE_PARAMS ike_prf;
7817 CK_NSS_IKE_PRF_PLUS_DERIVE_PARAMS ike2_prf;
7818 CK_EXTRACT_PARAMS subset_params;
7819 CK_RV crv;
7820
7821 /* set up PKCS #11 parameters */
7822 ike_mech.pParameter = &ike_prf;
7823 ike_mech.ulParameterLen = sizeof(ike_prf);
7824 ike2_mech.pParameter = &ike2_prf;
7825 ike2_mech.ulParameterLen = sizeof(ike2_prf);
7826 subset_mech.pParameter = &subset_params;
7827 subset_mech.ulParameterLen = sizeof(subset_params);
7828 subset_params = 0;
7829 skeyseed_template.pValue = skeyseed_secret;
7830 skeyseed_template.ulValueLen = HASH_LENGTH_MAX64;
7831
7832 crv = NSC_Initialize((CK_VOID_PTR)&pk11args);
7833 if (crv != CKR_OK0x00000000UL) {
7834 fprintf(stderrstderr, "NSC_Initialize failed crv=0x%x\n", (unsigned int)crv);
7835 goto loser;
7836 }
7837 count = slotListCount;
7838 crv = NSC_GetSlotList(PR_TRUE1, slotList, &count);
7839 if (crv != CKR_OK0x00000000UL) {
7840 fprintf(stderrstderr, "NSC_GetSlotList failed crv=0x%x\n", (unsigned int)crv);
7841 goto loser;
7842 }
7843 if ((count > slotListCount) || count < 1) {
7844 fprintf(stderrstderr,
7845 "NSC_GetSlotList returned too many or too few slots: %d slots max=%d min=1\n",
7846 (int)count, (int)slotListCount);
7847 goto loser;
7848 }
7849 slotID = slotList[0];
7850 ikereq = fopen(reqfn, "r");
7851 ikeresp = stdoutstdout;
7852 while (fgets(buf, sizeof buf, ikereq) != NULL((void*)0)) {
7853 /* a comment or blank line */
7854 if (buf[0] == '#' || buf[0] == '\n') {
7855 fputs(buf, ikeresp);
7856 continue;
7857 }
7858 /* [.....] */
7859 if (buf[0] == '[') {
7860 if (strncmp(buf, "[SHA-1]", 7) == 0) {
7861 ike_prf.prfMechanism = CKM_SHA_1_HMAC0x00000221UL;
7862 ike2_prf.prfMechanism = CKM_SHA_1_HMAC0x00000221UL;
7863 }
7864 if (strncmp(buf, "[SHA-224]", 9) == 0) {
7865 ike_prf.prfMechanism = CKM_SHA224_HMAC0x00000256UL;
7866 ike2_prf.prfMechanism = CKM_SHA224_HMAC0x00000256UL;
7867 }
7868 if (strncmp(buf, "[SHA-256]", 9) == 0) {
7869 ike_prf.prfMechanism = CKM_SHA256_HMAC0x00000251UL;
7870 ike2_prf.prfMechanism = CKM_SHA256_HMAC0x00000251UL;
7871 }
7872 if (strncmp(buf, "[SHA-384]", 9) == 0) {
7873 ike_prf.prfMechanism = CKM_SHA384_HMAC0x00000261UL;
7874 ike2_prf.prfMechanism = CKM_SHA384_HMAC0x00000261UL;
7875 }
7876 if (strncmp(buf, "[SHA-512]", 9) == 0) {
7877 ike_prf.prfMechanism = CKM_SHA512_HMAC0x00000271UL;
7878 ike2_prf.prfMechanism = CKM_SHA512_HMAC0x00000271UL;
7879 }
7880 if (strncmp(buf, "[AES-XCBC", 9) == 0) {
7881 ike_prf.prfMechanism = CKM_AES_XCBC_MAC0x0000108CUL;
7882 ike2_prf.prfMechanism = CKM_AES_XCBC_MAC0x0000108CUL;
7883 }
7884 if (strncmp(buf, "[g^ir", 5) == 0) {
7885 if (sscanf(buf, "[g^ir length = %d]",
7886 &gir_len) != 1) {
7887 goto loser;
7888 }
7889 gir_len = gir_len / 8;
7890 if (gir)
7891 free(gir);
7892 if (gir_new)
7893 free(gir_new);
7894 gir = malloc(gir_len);
7895 gir_new = malloc(gir_len);
7896 gir_template[0].pValue = gir;
7897 gir_template[0].ulValueLen = gir_len;
7898 gir_new_template[0].pValue = gir_new;
7899 gir_new_template[0].ulValueLen = gir_len;
7900 }
7901 if (strncmp(buf, "[Ni", 3) == 0) {
7902 if (sscanf(buf, "[Ni length = %d]", &Ni_len) != 1) {
7903 goto loser;
7904 }
7905 Ni_len = Ni_len / 8;
7906 }
7907 if (strncmp(buf, "[Nr", 3) == 0) {
7908 if (sscanf(buf, "[Nr length = %d]", &Nr_len) != 1) {
7909 goto loser;
7910 }
7911 Nr_len = Nr_len / 8;
7912 }
7913 if (strncmp(buf, "[DKM", 4) == 0) {
7914 if (sscanf(buf, "[DKM length = %d]",
7915 &DKM_len) != 1) {
7916 goto loser;
7917 }
7918 DKM_len = DKM_len / 8;
7919 if (DKM)
7920 free(DKM);
7921 DKM = malloc(DKM_len);
7922 dkm_template.pValue = DKM;
7923 dkm_template.ulValueLen = DKM_len;
7924 }
7925 if (strncmp(buf, "[Child SA DKM", 13) == 0) {
7926 if (sscanf(buf, "[Child SA DKM length = %d]",
7927 &DKM_child_len) != 1) {
7928 goto loser;
7929 }
7930 DKM_child_len = DKM_child_len / 8;
7931 if (DKM_child)
7932 free(DKM_child);
7933 DKM_child = malloc(DKM_child_len);
7934 dkm_child_template.pValue = DKM_child;
7935 dkm_child_template.ulValueLen = DKM_child_len;
7936 }
7937 fputs(buf, ikeresp);
7938 continue;
7939 }
7940 /* "COUNT = x" begins a new data set */
7941 if (strncmp(buf, "COUNT", 5) == 0) {
7942 /* zeroize the variables for the test with this data set */
7943 int new_seed_len = Ni_len + Nr_len + SPIi_len + SPIr_len;
7944 if (seed_data_len != new_seed_len) {
7945 if (seed_data)
7946 free(seed_data);
7947 seed_data_len = new_seed_len;
7948 seed_data = malloc(seed_data_len);
7949 Ni = seed_data;
7950 Nr = &seed_data[Ni_len];
7951 SPIi = &seed_data[Ni_len + Nr_len];
7952 SPIr = &seed_data[new_seed_len - SPIr_len];
7953 ike_prf.pNi = Ni;
7954 ike_prf.ulNiLen = Ni_len;
7955 ike_prf.pNr = Nr;
7956 ike_prf.ulNrLen = Nr_len;
7957 ike2_prf.pSeedData = seed_data;
7958 }
7959 memset(gir, 0, gir_len);
7960 memset(gir_new, 0, gir_len);
7961 memset(seed_data, 0, seed_data_len);
7962 fputs(buf, ikeresp);
7963 continue;
7964 }
7965 /* Ni = ... */
7966 if (strncmp(buf, "Ni", 2) == 0) {
7967 i = 2;
7968 while (isspace(buf[i])((*__ctype_b_loc ())[(int) ((buf[i]))] & (unsigned short int
) _ISspace)
|| buf[i] == '=') {
7969 i++;
7970 }
7971 for (j = 0; j < Ni_len; i += 2, j++) {
7972 hex_to_byteval(&buf[i], &Ni[j]);
7973 }
7974 fputs(buf, ikeresp);
7975 continue;
7976 }
7977 /* Nr = ... */
7978 if (strncmp(buf, "Nr", 2) == 0) {
7979 i = 2;
7980 while (isspace(buf[i])((*__ctype_b_loc ())[(int) ((buf[i]))] & (unsigned short int
) _ISspace)
|| buf[i] == '=') {
7981 i++;
7982 }
7983 for (j = 0; j < Nr_len; i += 2, j++) {
7984 hex_to_byteval(&buf[i], &Nr[j]);
7985 }
7986 fputs(buf, ikeresp);
7987 continue;
7988 }
7989 /* g^ir (new) = ... */
7990 if (strncmp(buf, "g^ir (new)", 10) == 0) {
7991 i = 10;
7992 while (isspace(buf[i])((*__ctype_b_loc ())[(int) ((buf[i]))] & (unsigned short int
) _ISspace)
|| buf[i] == '=') {
7993 i++;
7994 }
7995 for (j = 0; j < gir_len; i += 2, j++) {
7996 hex_to_byteval(&buf[i], &gir_new[j]);
7997 }
7998 fputs(buf, ikeresp);
7999 continue;
8000 }
8001 /* g^ir = ... */
8002 if (strncmp(buf, "g^ir", 4) == 0) {
8003 i = 4;
8004 while (isspace(buf[i])((*__ctype_b_loc ())[(int) ((buf[i]))] & (unsigned short int
) _ISspace)
|| buf[i] == '=') {
8005 i++;
8006 }
8007 for (j = 0; j < gir_len; i += 2, j++) {
8008 hex_to_byteval(&buf[i], &gir[j]);
8009 }
8010 fputs(buf, ikeresp);
8011 continue;
8012 }
8013 /* SPIi = ... */
8014 if (strncmp(buf, "SPIi", 4) == 0) {
8015 i = 4;
8016 while (isspace(buf[i])((*__ctype_b_loc ())[(int) ((buf[i]))] & (unsigned short int
) _ISspace)
|| buf[i] == '=') {
8017 i++;
8018 }
8019 for (j = 0; j < SPIi_len; i += 2, j++) {
8020 hex_to_byteval(&buf[i], &SPIi[j]);
8021 }
8022 fputs(buf, ikeresp);
8023 continue;
8024 }
8025 /* SPIr = ... */
8026 if (strncmp(buf, "SPIr", 4) == 0) {
8027 CK_SESSION_HANDLE session;
8028 CK_OBJECT_HANDLE gir_handle;
8029 CK_OBJECT_HANDLE gir_new_handle;
8030 CK_OBJECT_HANDLE skeyseed_handle;
8031 CK_OBJECT_HANDLE sk_d_handle;
8032 CK_OBJECT_HANDLE skeyseed_new_handle;
8033 CK_OBJECT_HANDLE dkm_handle;
8034 CK_OBJECT_HANDLE dkm_child_handle;
8035 i = 4;
8036 while (isspace(buf[i])((*__ctype_b_loc ())[(int) ((buf[i]))] & (unsigned short int
) _ISspace)
|| buf[i] == '=') {
8037 i++;
8038 }
8039 for (j = 0; j < SPIr_len; i += 2, j++) {
8040 hex_to_byteval(&buf[i], &SPIr[j]);
8041 }
8042 fputs(buf, ikeresp);
8043 crv = NSC_OpenSession(slotID, 0, NULL((void*)0), NULL((void*)0), &session);
8044 if (crv != CKR_OK0x00000000UL) {
8045 fprintf(stderrstderr, "NSC_OpenSession failed crv=0x%x\n",
8046 (unsigned int)crv);
8047 goto loser;
8048 }
8049 crv = NSC_CreateObject(session, gir_template,
8050 gir_template_count, &gir_handle);
8051 if (crv != CKR_OK0x00000000UL) {
8052 fprintf(stderrstderr, "NSC_CreateObject (g^ir) failed crv=0x%x\n",
8053 (unsigned int)crv);
8054 goto loser;
8055 }
8056 crv = NSC_CreateObject(session, gir_new_template,
8057 gir_new_template_count, &gir_new_handle);
8058 if (crv != CKR_OK0x00000000UL) {
8059 fprintf(stderrstderr, "NSC_CreateObject (g^ir new) failed crv=0x%x\n",
8060 (unsigned int)crv);
8061 goto loser;
8062 }
8063 /* get the SKEYSEED key */
8064 ike_prf.bDataAsKey = CK_TRUE1;
8065 ike_prf.bRekey = CK_FALSE0;
8066 ike_prf.hNewKey = CK_INVALID_HANDLE0;
8067 crv = NSC_DeriveKey(session, &ike_mech, gir_handle,
8068 derive_template, derive_template_count - 1,
8069 &skeyseed_handle);
8070 if (crv != CKR_OK0x00000000UL) {
8071 fprintf(stderrstderr, "NSC_DeriveKey(skeyid) failed crv=0x%x\n",
8072 (unsigned int)crv);
8073 goto loser;
8074 }
8075 skeyseed_template.ulValueLen = HASH_LENGTH_MAX64;
8076 crv = NSC_GetAttributeValue(session, skeyseed_handle,
8077 &skeyseed_template, 1);
8078 if (crv != CKR_OK0x00000000UL) {
8079 fprintf(stderrstderr, "NSC_GetAttribute(skeyid) failed crv=0x%x\n",
8080 (unsigned int)crv);
8081 goto loser;
8082 }
8083 fputs("SKEYSEED = ", ikeresp);
8084 to_hex_str(buf, skeyseed_secret, skeyseed_template.ulValueLen);
8085 fputs(buf, ikeresp);
8086 fputc('\n', ikeresp);
8087
8088 /* get DKM */
8089 keyLen = DKM_len;
8090 ike2_prf.bHasSeedKey = CK_FALSE0;
8091 ike2_prf.hSeedKey = CK_INVALID_HANDLE0;
8092 ike2_prf.ulSeedDataLen = seed_data_len;
8093 crv = NSC_DeriveKey(session, &ike2_mech, skeyseed_handle,
8094 derive_template, derive_template_count,
8095 &dkm_handle);
8096 if (crv != CKR_OK0x00000000UL) {
8097 fprintf(stderrstderr, "NSC_DeriveKey(DKM) failed crv=0x%x\n",
8098 (unsigned int)crv);
8099 goto loser;
8100 }
8101 crv = NSC_GetAttributeValue(session, dkm_handle,
8102 &dkm_template, 1);
8103 if (crv != CKR_OK0x00000000UL) {
8104 fprintf(stderrstderr, "NSC_GetAttribute(DKM) failed crv=0x%x\n",
8105 (unsigned int)crv);
8106 goto loser;
8107 }
8108 fputs("DKM = ", ikeresp);
8109 to_hex_str(buf, DKM, DKM_len);
8110 fputs(buf, ikeresp);
8111 fputc('\n', ikeresp);
8112
8113 /* get the sk_d from the DKM */
8114 keyLen = skeyseed_template.ulValueLen;
8115 crv = NSC_DeriveKey(session, &subset_mech, dkm_handle,
8116 derive_template, derive_template_count,
8117 &sk_d_handle);
8118 if (crv != CKR_OK0x00000000UL) {
8119 fprintf(stderrstderr, "NSC_DeriveKey(sk_d) failed crv=0x%x\n",
8120 (unsigned int)crv);
8121 goto loser;
8122 }
8123
8124 /* get DKM child */
8125 keyLen = DKM_child_len;
8126 ike2_prf.bHasSeedKey = CK_FALSE0;
8127 ike2_prf.hSeedKey = CK_INVALID_HANDLE0;
8128 ike2_prf.ulSeedDataLen = Ni_len + Nr_len;
8129 crv = NSC_DeriveKey(session, &ike2_mech, sk_d_handle,
8130 derive_template, derive_template_count,
8131 &dkm_child_handle);
8132 if (crv != CKR_OK0x00000000UL) {
8133 fprintf(stderrstderr, "NSC_DeriveKey(DKM Child SA) failed crv=0x%x\n",
8134 (unsigned int)crv);
8135 goto loser;
8136 }
8137 crv = NSC_GetAttributeValue(session, dkm_child_handle,
8138 &dkm_child_template, 1);
8139 if (crv != CKR_OK0x00000000UL) {
8140 fprintf(stderrstderr, "NSC_GetAttribute(DKM Child SA) failed crv=0x%x\n",
8141 (unsigned int)crv);
8142 goto loser;
8143 }
8144 fputs("DKM(Child SA) = ", ikeresp);
8145 to_hex_str(buf, DKM_child, DKM_child_len);
8146 fputs(buf, ikeresp);
8147 fputc('\n', ikeresp);
8148
8149 /* get DKM child D-H*/
8150 keyLen = DKM_child_len;
8151 ike2_prf.bHasSeedKey = CK_TRUE1;
8152 ike2_prf.hSeedKey = gir_new_handle;
8153 ike2_prf.ulSeedDataLen = Ni_len + Nr_len;
8154 crv = NSC_DeriveKey(session, &ike2_mech, sk_d_handle,
8155 derive_template, derive_template_count,
8156 &dkm_child_handle);
8157 if (crv != CKR_OK0x00000000UL) {
8158 fprintf(stderrstderr, "NSC_DeriveKey(DKM Child SA D-H) failed crv=0x%x\n",
8159 (unsigned int)crv);
8160 goto loser;
8161 }
8162 crv = NSC_GetAttributeValue(session, dkm_child_handle,
8163 &dkm_child_template, 1);
8164 if (crv != CKR_OK0x00000000UL) {
8165 fprintf(stderrstderr, "NSC_GetAttribute(DKM Child SA D-H) failed crv=0x%x\n",
8166 (unsigned int)crv);
8167 goto loser;
8168 }
8169 fputs("DKM(Child SA D-H) = ", ikeresp);
8170 to_hex_str(buf, DKM_child, DKM_child_len);
8171 fputs(buf, ikeresp);
8172 fputc('\n', ikeresp);
8173
8174 /* get SKEYSEED(rekey) */
8175 ike_prf.bDataAsKey = CK_FALSE0;
8176 ike_prf.bRekey = CK_TRUE1;
8177 ike_prf.hNewKey = gir_new_handle;
8178 crv = NSC_DeriveKey(session, &ike_mech, sk_d_handle,
8179 derive_template, derive_template_count - 1,
8180 &skeyseed_new_handle);
8181 if (crv != CKR_OK0x00000000UL) {
8182 fprintf(stderrstderr, "NSC_DeriveKey(skeyid rekey) failed crv=0x%x\n",
8183 (unsigned int)crv);
8184 goto loser;
8185 }
8186 skeyseed_template.ulValueLen = HASH_LENGTH_MAX64;
8187 crv = NSC_GetAttributeValue(session, skeyseed_new_handle,
8188 &skeyseed_template, 1);
8189 if (crv != CKR_OK0x00000000UL) {
8190 fprintf(stderrstderr, "NSC_GetAttribute(skeyid) failed crv=0x%x\n",
8191 (unsigned int)crv);
8192 goto loser;
8193 }
8194 fputs("SKEYSEED(rekey) = ", ikeresp);
8195 to_hex_str(buf, skeyseed_secret, skeyseed_template.ulValueLen);
8196 fputs(buf, ikeresp);
8197 fputc('\n', ikeresp);
8198
8199 crv = NSC_CloseSession(session);
8200 continue;
8201 }
8202 }
8203loser:
8204 NSC_Finalize(NULL((void*)0));
8205 if (gir)
8206 free(gir);
8207 if (gir_new)
8208 free(gir_new);
8209 if (seed_data)
8210 free(seed_data);
8211 if (DKM)
8212 free(DKM);
8213 if (DKM_child)
8214 free(DKM_child);
8215 if (ikereq)
8216 fclose(ikereq);
8217}
8218
8219void
8220kbkdf(char *path)
8221{
8222 /* == Parser data == */
8223 char buf[610]; /* holds one line from the input REQUEST file. Needs to
8224 * be large enough to hold the longest line:
8225 * "KO = <600 hex digits>\n". */
8226 CK_ULONG L;
8227 unsigned char KI[64];
8228 unsigned int KI_len = 64;
8229 unsigned char KO[300];
8230 unsigned int KO_len = 300;
8231 /* This is used only with feedback mode. */
8232 unsigned char IV[64];
8233 unsigned int IV_len = 64;
8234 /* These are only used in counter mode with counter location as
8235 * MIDDLE_FIXED. */
8236 unsigned char BeforeFixedInputData[50];
8237 unsigned int BeforeFixedInputData_len = 50;
8238 unsigned char AfterFixedInputData[10];
8239 unsigned int AfterFixedInputData_len = 10;
8240 /* These are used with every KDF type. */
8241 unsigned char FixedInputData[60];
8242 unsigned int FixedInputData_len = 60;
8243
8244 /* Counter locations:
8245 *
8246 * 0: not used
8247 * 1: beginning
8248 * 2: middle
8249 * 3: end */
8250 int ctr_location = 0;
8251 CK_ULONG counter_bitlen = 0;
8252
8253 size_t buf_offset;
8254 size_t offset;
8255
8256 FILE *kbkdf_req = NULL((void*)0);
8257 FILE *kbkdf_resp = NULL((void*)0);
8258
8259 /* == PKCS#11 data == */
8260 CK_RV crv;
8261
8262 CK_SLOT_ID slotList[10];
8263 CK_SLOT_ID slotID;
8264 CK_ULONG slotListCount = sizeof(slotList) / sizeof(slotList[0]);
8265 CK_ULONG slotCount = 0;
8266
8267 CK_MECHANISM kdf = { 0 };
8268
8269 CK_MECHANISM_TYPE prf_mech = 0;
8270 CK_BBOOL ck_true = CK_TRUE1;
8271
8272 /* We never need more than 3 data parameters. */
8273 CK_PRF_DATA_PARAM dataParams[3];
8274 CK_ULONG dataParams_len = 3;
8275
8276 CK_SP800_108_COUNTER_FORMAT iterator = { CK_FALSE0, 0 };
8277
8278 CK_SP800_108_KDF_PARAMS kdfParams = { 0 };
8279 CK_SP800_108_FEEDBACK_KDF_PARAMS feedbackParams = { 0 };
8280
8281 CK_OBJECT_CLASS ck_secret_key = CKO_SECRET_KEY0x00000004UL;
8282 CK_KEY_TYPE ck_generic = CKK_GENERIC_SECRET0x00000010UL;
8283
8284 CK_ATTRIBUTE prf_template[] = {
8285 { CKA_VALUE0x00000011UL, &KI, sizeof(KI) },
8286 { CKA_CLASS0x00000000UL, &ck_secret_key, sizeof(ck_secret_key) },
8287 { CKA_KEY_TYPE0x00000100UL, &ck_generic, sizeof(ck_generic) },
8288 { CKA_DERIVE0x0000010CUL, &ck_true, sizeof(ck_true) }
8289 };
8290 CK_ULONG prf_template_count = sizeof(prf_template) / sizeof(prf_template[0]);
8291
8292 CK_ATTRIBUTE derive_template[] = {
8293 { CKA_CLASS0x00000000UL, &ck_secret_key, sizeof(ck_secret_key) },
8294 { CKA_KEY_TYPE0x00000100UL, &ck_generic, sizeof(ck_generic) },
8295 { CKA_DERIVE0x0000010CUL, &ck_true, sizeof(ck_true) },
8296 { CKA_VALUE_LEN0x00000161UL, &L, sizeof(L) }
8297 };
8298 CK_ULONG derive_template_count = sizeof(derive_template) / sizeof(derive_template[0]);
8299
8300 CK_ATTRIBUTE output_key = { CKA_VALUE0x00000011UL, KO, KO_len };
8301
8302 const CK_C_INITIALIZE_ARGS pk11args = {
8303 NULL((void*)0), NULL((void*)0), NULL((void*)0), NULL((void*)0), CKF_LIBRARY_CANT_CREATE_OS_THREADS0x00000001UL,
8304 (void *)"flags=readOnly,noCertDB,noModDB", NULL((void*)0)
8305 };
8306
8307 /* == Start up PKCS#11 == */
8308 crv = NSC_Initialize((CK_VOID_PTR)&pk11args);
8309 if (crv != CKR_OK0x00000000UL) {
8310 fprintf(stderrstderr, "NSC_Initialize failed crv=0x%x\n", (unsigned int)crv);
8311 goto done;
8312 }
8313
8314 slotCount = slotListCount;
8315 crv = NSC_GetSlotList(PR_TRUE1, slotList, &slotCount);
8316 if (crv != CKR_OK0x00000000UL) {
8317 fprintf(stderrstderr, "NSC_GetSlotList failed crv=0x%x\n", (unsigned int)crv);
8318 goto done;
8319 }
8320 if ((slotCount > slotListCount) || slotCount < 1) {
8321 fprintf(stderrstderr,
8322 "NSC_GetSlotList returned too many or too few slots: %d slots max=%d min=1\n",
8323 (int)slotCount, (int)slotListCount);
8324 goto done;
8325 }
8326 slotID = slotList[0];
8327
8328 /* == Start parsing the file == */
8329 kbkdf_req = fopen(path, "r");
8330 kbkdf_resp = stdoutstdout;
8331
8332 while (fgets(buf, sizeof buf, kbkdf_req) != NULL((void*)0)) {
8333 /* If we have a comment, check if it tells us the type of KDF to use.
8334 * This differs per-file, so we have to parse it. */
8335 if (buf[0] == '#' || buf[0] == '\n' || buf[0] == '\r') {
8336 if (strncmp(buf, "# KDF Mode Supported: Counter Mode", 34) == 0) {
8337 kdf.mechanism = CKM_SP800_108_COUNTER_KDF0x000003acUL;
8338 }
8339 if (strncmp(buf, "# KDF Mode Supported: Feedback Mode", 35) == 0) {
8340 kdf.mechanism = CKM_SP800_108_FEEDBACK_KDF0x000003adUL;
8341 }
8342 if (strncmp(buf, "# KDF Mode Supported: DblPipeline Mode", 38) == 0) {
8343 kdf.mechanism = CKM_SP800_108_DOUBLE_PIPELINE_KDF0x000003aeUL;
8344 }
8345
8346 fputs(buf, kbkdf_resp);
8347 continue;
8348 }
8349
8350 /* [....] - context directive */
8351 if (buf[0] == '[') {
8352 /* PRF begins each new section. */
8353 if (strncmp(buf, "[PRF=CMAC_AES128]", 17) == 0) {
8354 prf_mech = CKM_AES_CMAC0x0000108AUL;
8355 KI_len = 16;
8356 } else if (strncmp(buf, "[PRF=CMAC_AES192]", 17) == 0) {
8357 prf_mech = CKM_AES_CMAC0x0000108AUL;
8358 KI_len = 24;
8359 } else if (strncmp(buf, "[PRF=CMAC_AES256]", 17) == 0) {
8360 prf_mech = CKM_AES_CMAC0x0000108AUL;
8361 KI_len = 32;
8362 } else if (strncmp(buf, "[PRF=HMAC_SHA1]", 15) == 0) {
8363 prf_mech = CKM_SHA_1_HMAC0x00000221UL;
8364 KI_len = 20;
8365 } else if (strncmp(buf, "[PRF=HMAC_SHA224]", 17) == 0) {
8366 prf_mech = CKM_SHA224_HMAC0x00000256UL;
8367 KI_len = 28;
8368 } else if (strncmp(buf, "[PRF=HMAC_SHA256]", 17) == 0) {
8369 prf_mech = CKM_SHA256_HMAC0x00000251UL;
8370 KI_len = 32;
8371 } else if (strncmp(buf, "[PRF=HMAC_SHA384]", 17) == 0) {
8372 prf_mech = CKM_SHA384_HMAC0x00000261UL;
8373 KI_len = 48;
8374 } else if (strncmp(buf, "[PRF=HMAC_SHA512]", 17) == 0) {
8375 prf_mech = CKM_SHA512_HMAC0x00000271UL;
8376 KI_len = 64;
8377 } else if (strncmp(buf, "[PRF=", 5) == 0) {
8378 fprintf(stderrstderr, "Invalid or unsupported PRF mechanism: %s\n", buf);
8379 goto done;
8380 }
8381
8382 /* Then comes counter, if present. */
8383 if (strncmp(buf, "[CTRLOCATION=BEFORE_FIXED]", 26) == 0 ||
8384 strncmp(buf, "[CTRLOCATION=BEFORE_ITER]", 24) == 0) {
8385 ctr_location = 1;
8386 }
8387 if (strncmp(buf, "[CTRLOCATION=MIDDLE_FIXED]", 26) == 0 ||
8388 strncmp(buf, "[CTRLOCATION=AFTER_ITER]", 24) == 0) {
8389 ctr_location = 2;
8390 }
8391 if (strncmp(buf, "[CTRLOCATION=AFTER_FIXED]", 25) == 0) {
8392 ctr_location = 3;
8393 }
8394
8395 /* If counter is present, then we need to know its size. */
8396 if (strncmp(buf, "[RLEN=", 6) == 0) {
8397 if (sscanf(buf, "[RLEN=%lu_BITS]", &counter_bitlen) != 1) {
8398 goto done;
8399 }
8400 }
8401
8402 fputs(buf, kbkdf_resp);
8403 continue;
8404 }
8405
8406 /* Each test contains a counter, an output length L, an input key KI,
8407 * maybe an initialization vector IV, one of a couple of fixed data
8408 * buffers, and finally the output key KO. */
8409
8410 /* First comes COUNT. */
8411 if (strncmp(buf, "COUNT=", 6) == 0) {
8412 /* Clear all out data fields on each test. */
8413 memset(KI, 0, sizeof KI);
8414 memset(KO, 0, sizeof KO);
8415 memset(IV, 0, sizeof IV);
8416 memset(BeforeFixedInputData, 0, sizeof BeforeFixedInputData);
8417 memset(AfterFixedInputData, 0, sizeof AfterFixedInputData);
8418 memset(FixedInputData, 0, sizeof FixedInputData);
8419
8420 /* Then reset lengths except KI: it was determined by PRF
8421 * selection above. */
8422 KO_len = 0;
8423 IV_len = 0;
8424 BeforeFixedInputData_len = 0;
8425 AfterFixedInputData_len = 0;
8426 FixedInputData_len = 0;
8427
8428 fputs(buf, kbkdf_resp);
8429 continue;
8430 }
8431
8432 /* Then comes L. */
8433 if (strncmp(buf, "L = ", 4) == 0) {
8434 if (sscanf(buf, "L = %lu", &L) != 1) {
8435 goto done;
8436 }
8437
8438 if ((L % 8) != 0) {
8439 fprintf(stderrstderr, "Assumption that L was length in bits incorrect: %lu - %s", L, buf);
8440 fprintf(stderrstderr, "Note that NSS only supports byte-aligned outputs and not bit-aligned outputs.\n");
8441 goto done;
8442 }
8443
8444 L = L / 8;
8445
8446 fputs(buf, kbkdf_resp);
8447 continue;
8448 }
8449
8450 /* Then comes KI. */
8451 if (strncmp(buf, "KI = ", 5) == 0) {
8452 buf_offset = 5;
8453
8454 for (offset = 0; offset < KI_len; offset++, buf_offset += 2) {
8455 hex_to_byteval(buf + buf_offset, KI + offset);
8456 }
8457
8458 fputs(buf, kbkdf_resp);
8459 continue;
8460 }
8461
8462 /* Then comes IVlen and IV, if present. */
8463 if (strncmp(buf, "IVlen = ", 8) == 0) {
8464 if (sscanf(buf, "IVlen = %u", &IV_len) != 1) {
8465 goto done;
8466 }
8467
8468 if ((IV_len % 8) != 0) {
8469 fprintf(stderrstderr, "Assumption that IV_len was length in bits incorrect: %u - %s. ", IV_len, buf);
8470 fprintf(stderrstderr, "Note that NSS only supports byte-aligned inputs and not bit-aligned inputs.\n");
8471 goto done;
8472 }
8473
8474 /* Need the IV length in bytes, not bits. */
8475 IV_len = IV_len / 8;
8476
8477 fputs(buf, kbkdf_resp);
8478 continue;
8479 }
8480 if (strncmp(buf, "IV = ", 5) == 0) {
8481 buf_offset = 5;
8482
8483 for (offset = 0; offset < IV_len; offset++, buf_offset += 2) {
8484 hex_to_byteval(buf + buf_offset, IV + offset);
8485 }
8486
8487 fputs(buf, kbkdf_resp);
8488 continue;
8489 }
8490
8491 /* We might have DataBeforeCtr and DataAfterCtr if present. */
8492 if (strncmp(buf, "DataBeforeCtrLen = ", 19) == 0) {
8493 if (sscanf(buf, "DataBeforeCtrLen = %u", &BeforeFixedInputData_len) != 1) {
8494 goto done;
8495 }
8496
8497 fputs(buf, kbkdf_resp);
8498 continue;
8499 }
8500 if (strncmp(buf, "DataBeforeCtrData = ", 20) == 0) {
8501 buf_offset = 20;
8502
8503 for (offset = 0; offset < BeforeFixedInputData_len; offset++, buf_offset += 2) {
8504 hex_to_byteval(buf + buf_offset, BeforeFixedInputData + offset);
8505 }
8506
8507 fputs(buf, kbkdf_resp);
8508 continue;
8509 }
8510 if (strncmp(buf, "DataAfterCtrLen = ", 18) == 0) {
8511 if (sscanf(buf, "DataAfterCtrLen = %u", &AfterFixedInputData_len) != 1) {
8512 goto done;
8513 }
8514
8515 fputs(buf, kbkdf_resp);
8516 continue;
8517 }
8518 if (strncmp(buf, "DataAfterCtrData = ", 19) == 0) {
8519 buf_offset = 19;
8520
8521 for (offset = 0; offset < AfterFixedInputData_len; offset++, buf_offset += 2) {
8522 hex_to_byteval(buf + buf_offset, AfterFixedInputData + offset);
8523 }
8524
8525 fputs(buf, kbkdf_resp);
8526 continue;
8527 }
8528
8529 /* Otherwise, we might have FixedInputData, if present. */
8530 if (strncmp(buf, "FixedInputDataByteLen = ", 24) == 0) {
8531 if (sscanf(buf, "FixedInputDataByteLen = %u", &FixedInputData_len) != 1) {
8532 goto done;
8533 }
8534
8535 fputs(buf, kbkdf_resp);
8536 continue;
8537 }
8538 if (strncmp(buf, "FixedInputData = ", 17) == 0) {
8539 buf_offset = 17;
8540
8541 for (offset = 0; offset < FixedInputData_len; offset++, buf_offset += 2) {
8542 hex_to_byteval(buf + buf_offset, FixedInputData + offset);
8543 }
8544
8545 fputs(buf, kbkdf_resp);
8546 continue;
8547 }
8548
8549 /* Finally, run the KBKDF calculation when KO is passed. */
8550 if (strncmp(buf, "KO = ", 5) == 0) {
8551 CK_SESSION_HANDLE session;
8552 CK_OBJECT_HANDLE prf_key;
8553 CK_OBJECT_HANDLE derived_key;
8554
8555 /* Open the session. */
8556 crv = NSC_OpenSession(slotID, 0, NULL((void*)0), NULL((void*)0), &session);
8557 if (crv != CKR_OK0x00000000UL) {
8558 fprintf(stderrstderr, "NSC_OpenSession failed crv=0x%x\n", (unsigned int)crv);
8559 goto done;
8560 }
8561
8562 /* Create the PRF key object. */
8563 prf_template[0].ulValueLen = KI_len;
8564 crv = NSC_CreateObject(session, prf_template, prf_template_count, &prf_key);
8565 if (crv != CKR_OK0x00000000UL) {
8566 fprintf(stderrstderr, "NSC_CreateObject (prf_key) failed crv=0x%x\n", (unsigned int)crv);
8567 goto done;
8568 }
8569
8570 /* Set up the KDF parameters. */
8571 if (kdf.mechanism == CKM_SP800_108_COUNTER_KDF0x000003acUL) {
8572 /* Counter operates in one of three ways: counter before fixed
8573 * input data, counter between fixed input data, and counter
8574 * after fixed input data. In all cases, we have an iterator.
8575 */
8576 iterator.ulWidthInBits = counter_bitlen;
8577
8578 if (ctr_location == 0 || ctr_location > 3) {
8579 fprintf(stderrstderr, "Expected ctr_location != 0 for Counter Mode KDF but got 0.\n");
8580 goto done;
8581 } else if (ctr_location == 1) {
8582 /* Counter before */
8583 dataParams[0].type = CK_SP800_108_ITERATION_VARIABLE0x00000001UL;
8584 dataParams[0].pValue = &iterator;
8585 dataParams[0].ulValueLen = sizeof(iterator);
8586
8587 dataParams[1].type = CK_SP800_108_BYTE_ARRAY0x00000004UL;
8588 dataParams[1].pValue = FixedInputData;
8589 dataParams[1].ulValueLen = FixedInputData_len;
8590
8591 dataParams_len = 2;
8592 } else if (ctr_location == 2) {
8593 /* Counter between */
8594 dataParams[0].type = CK_SP800_108_BYTE_ARRAY0x00000004UL;
8595 dataParams[0].pValue = BeforeFixedInputData;
8596 dataParams[0].ulValueLen = BeforeFixedInputData_len;
8597
8598 dataParams[1].type = CK_SP800_108_ITERATION_VARIABLE0x00000001UL;
8599 dataParams[1].pValue = &iterator;
8600 dataParams[1].ulValueLen = sizeof(iterator);
8601
8602 dataParams[2].type = CK_SP800_108_BYTE_ARRAY0x00000004UL;
8603 dataParams[2].pValue = AfterFixedInputData;
8604 dataParams[2].ulValueLen = AfterFixedInputData_len;
8605
8606 dataParams_len = 3;
8607 } else {
8608 /* Counter after */
8609 dataParams[0].type = CK_SP800_108_BYTE_ARRAY0x00000004UL;
8610 dataParams[0].pValue = FixedInputData;
8611 dataParams[0].ulValueLen = FixedInputData_len;
8612
8613 dataParams[1].type = CK_SP800_108_ITERATION_VARIABLE0x00000001UL;
8614 dataParams[1].pValue = &iterator;
8615 dataParams[1].ulValueLen = sizeof(iterator);
8616
8617 dataParams_len = 2;
8618 }
8619 } else if (kdf.mechanism == CKM_SP800_108_FEEDBACK_KDF0x000003adUL || kdf.mechanism == CKM_SP800_108_DOUBLE_PIPELINE_KDF0x000003aeUL) {
8620 /* When counter_bitlen != 0, we have an optional counter. */
8621 if (counter_bitlen != 0) {
8622 iterator.ulWidthInBits = counter_bitlen;
8623
8624 if (ctr_location == 0 || ctr_location > 3) {
8625 fprintf(stderrstderr, "Expected ctr_location != 0 for Counter Mode KDF but got 0.\n");
8626 goto done;
8627 } else if (ctr_location == 1) {
8628 /* Counter before */
8629 dataParams[0].type = CK_SP800_108_OPTIONAL_COUNTER0x00000002UL;
8630 dataParams[0].pValue = &iterator;
8631 dataParams[0].ulValueLen = sizeof(iterator);
8632
8633 dataParams[1].type = CK_SP800_108_ITERATION_VARIABLE0x00000001UL;
8634 dataParams[1].pValue = NULL((void*)0);
8635 dataParams[1].ulValueLen = 0;
8636
8637 dataParams[2].type = CK_SP800_108_BYTE_ARRAY0x00000004UL;
8638 dataParams[2].pValue = FixedInputData;
8639 dataParams[2].ulValueLen = FixedInputData_len;
8640
8641 dataParams_len = 3;
8642 } else if (ctr_location == 2) {
8643 /* Counter between */
8644 dataParams[0].type = CK_SP800_108_ITERATION_VARIABLE0x00000001UL;
8645 dataParams[0].pValue = NULL((void*)0);
8646 dataParams[0].ulValueLen = 0;
8647
8648 dataParams[1].type = CK_SP800_108_OPTIONAL_COUNTER0x00000002UL;
8649 dataParams[1].pValue = &iterator;
8650 dataParams[1].ulValueLen = sizeof(iterator);
8651
8652 dataParams[2].type = CK_SP800_108_BYTE_ARRAY0x00000004UL;
8653 dataParams[2].pValue = FixedInputData;
8654 dataParams[2].ulValueLen = FixedInputData_len;
8655
8656 dataParams_len = 3;
8657 } else {
8658 /* Counter after */
8659 dataParams[0].type = CK_SP800_108_ITERATION_VARIABLE0x00000001UL;
8660 dataParams[0].pValue = NULL((void*)0);
8661 dataParams[0].ulValueLen = 0;
8662
8663 dataParams[1].type = CK_SP800_108_BYTE_ARRAY0x00000004UL;
8664 dataParams[1].pValue = FixedInputData;
8665 dataParams[1].ulValueLen = FixedInputData_len;
8666
8667 dataParams[2].type = CK_SP800_108_OPTIONAL_COUNTER0x00000002UL;
8668 dataParams[2].pValue = &iterator;
8669 dataParams[2].ulValueLen = sizeof(iterator);
8670
8671 dataParams_len = 3;
8672 }
8673 } else {
8674 dataParams[0].type = CK_SP800_108_ITERATION_VARIABLE0x00000001UL;
8675 dataParams[0].pValue = NULL((void*)0);
8676 dataParams[0].ulValueLen = 0;
8677
8678 dataParams[1].type = CK_SP800_108_BYTE_ARRAY0x00000004UL;
8679 dataParams[1].pValue = FixedInputData;
8680 dataParams[1].ulValueLen = FixedInputData_len;
8681
8682 dataParams_len = 2;
8683 }
8684 }
8685
8686 if (kdf.mechanism != CKM_SP800_108_FEEDBACK_KDF0x000003adUL) {
8687 kdfParams.prfType = prf_mech;
8688 kdfParams.ulNumberOfDataParams = dataParams_len;
8689 kdfParams.pDataParams = dataParams;
8690
8691 kdf.pParameter = &kdfParams;
8692 kdf.ulParameterLen = sizeof(kdfParams);
8693 } else {
8694 feedbackParams.prfType = prf_mech;
8695 feedbackParams.ulNumberOfDataParams = dataParams_len;
8696 feedbackParams.pDataParams = dataParams;
8697 feedbackParams.ulIVLen = IV_len;
8698 if (IV_len == 0) {
8699 feedbackParams.pIV = NULL((void*)0);
8700 } else {
8701 feedbackParams.pIV = IV;
8702 }
8703
8704 kdf.pParameter = &feedbackParams;
8705 kdf.ulParameterLen = sizeof(feedbackParams);
8706 }
8707
8708 crv = NSC_DeriveKey(session, &kdf, prf_key, derive_template, derive_template_count, &derived_key);
8709 if (crv != CKR_OK0x00000000UL) {
8710 fprintf(stderrstderr, "NSC_DeriveKey(derived_key) failed crv=0x%x\n", (unsigned int)crv);
8711 goto done;
8712 }
8713
8714 crv = NSC_GetAttributeValue(session, derived_key, &output_key, 1);
8715 if (crv != CKR_OK0x00000000UL) {
8716 fprintf(stderrstderr, "NSC_GetAttribute(derived_value) failed crv=0x%x\n", (unsigned int)crv);
8717 goto done;
8718 }
8719
8720 fputs("KO = ", kbkdf_resp);
8721 to_hex_str(buf, KO, output_key.ulValueLen);
8722 fputs(buf, kbkdf_resp);
8723 fputs("\r\n", kbkdf_resp);
8724
8725 continue;
8726 }
8727 }
8728
8729done:
8730 if (kbkdf_req != NULL((void*)0)) {
8731 fclose(kbkdf_req);
8732 }
8733 if (kbkdf_resp != stdoutstdout && kbkdf_resp != NULL((void*)0)) {
8734 fclose(kbkdf_resp);
8735 }
8736
8737 return;
8738}
8739
8740int
8741main(int argc, char **argv)
8742{
8743 if (argc < 2)
8744 exit(-1);
8745
8746 RNG_RNGInit();
8747 SECOID_Init();
8748
8749 /*************/
8750 /* TDEA */
8751 /*************/
8752 if (strcmp(argv[1], "tdea") == 0) {
8753 /* argv[2]=kat|mmt|mct argv[3]=ecb|cbc argv[4]=<test name>.req */
8754 if (strcmp(argv[2], "kat") == 0) {
8755 /* Known Answer Test (KAT) */
8756 tdea_kat_mmt(argv[4]);
8757 } else if (strcmp(argv[2], "mmt") == 0) {
8758 /* Multi-block Message Test (MMT) */
8759 tdea_kat_mmt(argv[4]);
8760 } else if (strcmp(argv[2], "mct") == 0) {
8761 /* Monte Carlo Test (MCT) */
8762 if (strcmp(argv[3], "ecb") == 0) {
8763 /* ECB mode */
8764 tdea_mct(NSS_DES_EDE32, argv[4]);
8765 } else if (strcmp(argv[3], "cbc") == 0) {
8766 /* CBC mode */
8767 tdea_mct(NSS_DES_EDE3_CBC3, argv[4]);
8768 }
8769 }
8770 /*************/
8771 /* AES */
8772 /*************/
8773 } else if (strcmp(argv[1], "aes") == 0) {
8774 /* argv[2]=kat|mmt|mct argv[3]=ecb|cbc argv[4]=<test name>.req */
8775 if (strcmp(argv[2], "kat") == 0) {
8776 /* Known Answer Test (KAT) */
8777 aes_kat_mmt(argv[4]);
8778 } else if (strcmp(argv[2], "mmt") == 0) {
8779 /* Multi-block Message Test (MMT) */
8780 aes_kat_mmt(argv[4]);
8781 } else if (strcmp(argv[2], "gcm") == 0) {
8782 if (strcmp(argv[3], "decrypt") == 0) {
8783 aes_gcm(argv[4], 0);
8784 } else if (strcmp(argv[3], "encrypt_extiv") == 0) {
8785 aes_gcm(argv[4], 1);
8786 } else if (strcmp(argv[3], "encrypt_intiv") == 0) {
8787 aes_gcm(argv[4], 2);
8788 }
8789 } else if (strcmp(argv[2], "mct") == 0) {
8790 /* Monte Carlo Test (MCT) */
8791 if (strcmp(argv[3], "ecb") == 0) {
8792 /* ECB mode */
8793 aes_ecb_mct(argv[4]);
8794 } else if (strcmp(argv[3], "cbc") == 0) {
8795 /* CBC mode */
8796 aes_cbc_mct(argv[4]);
8797 }
8798 }
8799 /*************/
8800 /* SHA */
8801 /*************/
8802 } else if (strcmp(argv[1], "sha") == 0) {
8803 sha_test(argv[2]);
8804 /*************/
8805 /* RSA */
8806 /*************/
8807 } else if (strcmp(argv[1], "rsa") == 0) {
8808 /* argv[2]=siggen|sigver */
8809 /* argv[3]=<test name>.req */
8810 if (strcmp(argv[2], "siggen") == 0) {
8811 /* Signature Generation Test */
8812 rsa_siggen_test(argv[3]);
8813 } else if (strcmp(argv[2], "sigver") == 0) {
8814 /* Signature Verification Test */
8815 rsa_sigver_test(argv[3]);
8816 } else if (strcmp(argv[2], "keypair") == 0) {
8817 /* Key Pair Generation Test */
8818 rsa_keypair_test(argv[3]);
8819 }
8820 /*************/
8821 /* HMAC */
8822 /*************/
8823 } else if (strcmp(argv[1], "hmac") == 0) {
8824 hmac_test(argv[2]);
8825 /*************/
8826 /* DSA */
8827 /*************/
8828 } else if (strcmp(argv[1], "dsa") == 0) {
8829 /* argv[2]=keypair|pqggen|pqgver|siggen|sigver */
8830 /* argv[3]=<test name>.req */
8831 if (strcmp(argv[2], "keypair") == 0) {
8832 /* Key Pair Generation Test */
8833 dsa_keypair_test(argv[3]);
8834 } else if (strcmp(argv[2], "pqggen") == 0) {
8835 /* Domain Parameter Generation Test */
8836 dsa_pqggen_test(argv[3]);
8837 } else if (strcmp(argv[2], "pqgver") == 0) {
8838 /* Domain Parameter Validation Test */
8839 dsa_pqgver_test(argv[3]);
8840 } else if (strcmp(argv[2], "siggen") == 0) {
8841 /* Signature Generation Test */
8842 dsa_siggen_test(argv[3]);
8843 } else if (strcmp(argv[2], "sigver") == 0) {
8844 /* Signature Verification Test */
8845 dsa_sigver_test(argv[3]);
8846 }
8847 /*************/
8848 /* ECDSA */
8849 /*************/
8850 } else if (strcmp(argv[1], "ecdsa") == 0) {
8851 /* argv[2]=keypair|pkv|siggen|sigver argv[3]=<test name>.req */
8852 if (strcmp(argv[2], "keypair") == 0) {
8853 /* Key Pair Generation Test */
8854 ecdsa_keypair_test(argv[3]);
8855 } else if (strcmp(argv[2], "pkv") == 0) {
8856 /* Public Key Validation Test */
8857 ecdsa_pkv_test(argv[3]);
8858 } else if (strcmp(argv[2], "siggen") == 0) {
8859 /* Signature Generation Test */
8860 ecdsa_siggen_test(argv[3]);
8861 } else if (strcmp(argv[2], "sigver") == 0) {
8862 /* Signature Verification Test */
8863 ecdsa_sigver_test(argv[3]);
8864 }
8865 /*************/
8866 /* ECDH */
8867 /*************/
8868 } else if (strcmp(argv[1], "ecdh") == 0) {
8869 /* argv[2]={init|resp}-{func|verify} argv[3]=<test name>.req */
8870 if (strcmp(argv[2], "init-func") == 0) {
8871 ecdh_functional(argv[3], 0);
8872 } else if (strcmp(argv[2], "resp-func") == 0) {
8873 ecdh_functional(argv[3], 1);
8874 } else if (strcmp(argv[2], "init-verify") == 0) {
8875 ecdh_verify(argv[3], 0);
8876 } else if (strcmp(argv[2], "resp-verify") == 0) {
8877 ecdh_verify(argv[3], 1);
8878 }
8879 /*************/
8880 /* DH */
8881 /*************/
8882 } else if (strcmp(argv[1], "dh") == 0) {
8883 /* argv[2]={init|resp}-{func|verify} argv[3]=<test name>.req */
8884 if (strcmp(argv[2], "init-func") == 0) {
8885 dh_functional(argv[3], 0);
8886 } else if (strcmp(argv[2], "resp-func") == 0) {
8887 dh_functional(argv[3], 1);
8888 } else if (strcmp(argv[2], "init-verify") == 0) {
8889 dh_verify(argv[3], 0);
8890 } else if (strcmp(argv[2], "resp-verify") == 0) {
8891 dh_verify(argv[3], 1);
8892 }
8893 /*************/
8894 /* RNG */
8895 /*************/
8896 } else if (strcmp(argv[1], "rng") == 0) {
8897 /* argv[2]=vst|mct argv[3]=<test name>.req */
8898 if (strcmp(argv[2], "vst") == 0) {
8899 /* Variable Seed Test */
8900 rng_vst(argv[3]);
8901 } else if (strcmp(argv[2], "mct") == 0) {
8902 /* Monte Carlo Test */
8903 rng_mct(argv[3]);
8904 }
8905 } else if (strcmp(argv[1], "drbg") == 0) {
8906 /* Variable Seed Test */
8907 drbg(argv[2]);
8908 } else if (strcmp(argv[1], "ddrbg") == 0) {
8909 debug = 1;
8910 drbg(argv[2]);
8911 } else if (strcmp(argv[1], "tls") == 0) {
8912 tls(argv[2]);
8913 } else if (strcmp(argv[1], "ikev1") == 0) {
8914 ikev1(argv[2]);
8915 } else if (strcmp(argv[1], "ikev1-psk") == 0) {
8916 ikev1_psk(argv[2]);
8917 } else if (strcmp(argv[1], "ikev2") == 0) {
8918 ikev2(argv[2]);
8919 } else if (strcmp(argv[1], "kbkdf") == 0) {
8920 kbkdf(argv[2]);
8921 }
8922 return 0;
8923}