Bug Summary

File:s/cmd/fipstest/fipstest.c
Warning:line 6800, column 13
3rd function call argument is an uninitialized 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;
1
'key_block_len' declared without an initial value
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) {
2
Assuming 'crv' is equal to CKR_OK
3
Taking false branch
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) {
4
Assuming 'crv' is equal to CKR_OK
6703 fprintf(stderrstderr, "NSC_GetSlotList failed crv=0x%x\n", (unsigned int)crv);
6704 goto loser;
6705 }
6706 if ((count > slotListCount) || count < 1) {
5
Assuming 'count' is <= 'slotListCount'
6
Assuming 'count' is >= 1
7
Taking false branch
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)) {
8
Assuming the condition is true
22
Execution continues on line 6715
23
Assuming the condition is true
6716 /* a comment or blank line */
6717 if (buf[0] == '#' || buf[0] == '\n') {
9
Assuming the condition is false
10
Assuming the condition is false
11
Taking false branch
24
Assuming the condition is false
25
Assuming the condition is false
26
Taking false branch
6718 fputs(buf, tlsresp);
6719 continue;
6720 }
6721 /* [Xchange - SHA1] */
6722 if (buf[0] == '[') {
12
Assuming the condition is true
13
Taking true branch
27
Assuming the condition is false
28
Taking false branch
6723 if (strncmp(buf, "[TLS", 4) == 0) {
14
Assuming the condition is false
15
Taking false branch
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) {
16
Assuming the condition is true
17
Taking true branch
6765 if (sscanf(buf, "[pre-master secret length = %d]",
18
Assuming the condition is false
19
Taking false branch
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) {
20
Assuming the condition is false
21
Taking false branch
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) {
29
Assuming the condition is true
30
Taking true branch
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);
31
3rd function call argument is an uninitialized value
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;
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) {
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) {
7425 fprintf(stderrstderr, "NSC_GetSlotList failed crv=0x%x\n", (unsigned int)crv);
7426 goto loser;
7427 }
7428 if ((count > slotListCount) || count < 1) {
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)) {
7438 /* a comment or blank line */
7439 if (buf[0] == '#' || buf[0] == '\n') {
7440 fputs(buf, ikeresp);
7441 continue;
7442 }
7443 /* [.....] */
7444 if (buf[0] == '[') {
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) {
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) {
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) {
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) {
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) {
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) {
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) {
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] == '=') {
7600 i++;
7601 }
7602 for (j = 0; j < psk_len; i += 2, j++) {
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}