fips_dssvs.c 16.4 KB
Newer Older
1 2

#define OPENSSL_FIPSAPI
D
Dr. Stephen Henson 已提交
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
#include <openssl/opensslconf.h>

#ifndef OPENSSL_FIPS
#include <stdio.h>

int main(int argc, char **argv)
{
    printf("No FIPS DSA support\n");
    return(0);
}
#else

#include <openssl/bn.h>
#include <openssl/dsa.h>
#include <openssl/fips.h>
#include <openssl/err.h>
#include <openssl/evp.h>
#include <string.h>
#include <ctype.h>

#include "fips_utl.h"

25 26 27 28 29 30 31 32 33 34 35 36 37
static int parse_mod(char *line, int *pdsa2, int *pL, int *pN,
				const EVP_MD **pmd)
	{
	char lbuf[10240];
	char *keyword, *value;

	char *p;
	p = strchr(line, ',');
	if (!p)
		{
		*pL = atoi(line);
		*pdsa2 = 0;
		*pN = 160;
38 39
		if (pmd)
			*pmd = EVP_sha1();
40 41 42 43
		return 1;
		}
	*pdsa2 = 1;
	*p = 0;
44
	if (!parse_line2(&keyword, &value, lbuf, line, 0))
45 46 47 48 49
		return 0;
	if (strcmp(keyword, "L"))
		return 0;
	*pL = atoi(value);
	strcpy(line, p + 1);
50 51 52 53
	if (pmd)
		p = strchr(line, ',');
	else
		p = strchr(line, ']');
54 55 56
	if (!p)
		return 0;
	*p = 0;
57
	if (!parse_line2(&keyword, &value, lbuf, line, 0))
58 59 60 61
		return 0;
	if (strcmp(keyword, "N"))
		return 0;
	*pN = atoi(value);
62 63
	if (!pmd)
		return 1;
64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86
	strcpy(line, p + 1);
	p = strchr(line, ']');
	if (!p)
		return 0;
	*p = 0;
	p = line;
	while(isspace(*p))
		p++;
	if (!strcmp(p, "SHA-1"))
		*pmd = EVP_sha1();
	else if (!strcmp(p, "SHA-224"))
		*pmd = EVP_sha224();
	else if (!strcmp(p, "SHA-256"))
		*pmd = EVP_sha256();
	else if (!strcmp(p, "SHA-384"))
		*pmd = EVP_sha384();
	else if (!strcmp(p, "SHA-512"))
		*pmd = EVP_sha512();
	else
		return 0;
	return 1;
	}

87
static void primes(FILE *in, FILE *out)
D
Dr. Stephen Henson 已提交
88 89 90 91 92
    {
    char buf[10240];
    char lbuf[10240];
    char *keyword, *value;

93
    while(fgets(buf,sizeof buf,in) != NULL)
D
Dr. Stephen Henson 已提交
94
	{
95
	fputs(buf,out);
D
Dr. Stephen Henson 已提交
96 97 98 99 100 101 102 103
	if (!parse_line(&keyword, &value, lbuf, buf))
		continue;
	if(!strcmp(keyword,"Prime"))
	    {
	    BIGNUM *pp;

	    pp=BN_new();
	    do_hex2bn(&pp,value);
104
	    fprintf(out, "result= %c" RESP_EOL,
D
Dr. Stephen Henson 已提交
105 106 107 108 109 110 111 112 113
		   BN_is_prime_ex(pp,20,NULL,NULL) ? 'P' : 'F');
	    }	    
	}
    }

int dsa_builtin_paramgen(DSA *ret, size_t bits, size_t qbits,
	const EVP_MD *evpmd, const unsigned char *seed_in, size_t seed_len,
	unsigned char *seed_out,
	int *counter_ret, unsigned long *h_ret, BN_GENCB *cb);
114
int dsa_builtin_paramgen2(DSA *ret, size_t L, size_t N,
115
	const EVP_MD *evpmd, const unsigned char *seed_in, size_t seed_len,
116
	int idx, unsigned char *seed_out,
117
	int *counter_ret, unsigned long *h_ret, BN_GENCB *cb);
D
Dr. Stephen Henson 已提交
118

119 120
int dsa_paramgen_check_g(DSA *dsa);

121
static void pqg(FILE *in, FILE *out)
D
Dr. Stephen Henson 已提交
122 123 124 125
    {
    char buf[1024];
    char lbuf[1024];
    char *keyword, *value;
D
Dr. Stephen Henson 已提交
126 127
    int dsa2, L, N;
    const EVP_MD *md = NULL;
128 129 130 131 132
    BIGNUM *p = NULL, *q = NULL;
    enum pqtype { PQG_NONE, PQG_PQ, PQG_G, PQG_GCANON}
		pqg_type = PQG_NONE;
    int seedlen=-1, idxlen, idx = -1;
    unsigned char seed[1024], idtmp[1024];
D
Dr. Stephen Henson 已提交
133

134
    while(fgets(buf,sizeof buf,in) != NULL)
D
Dr. Stephen Henson 已提交
135
	{
136 137 138 139 140 141 142 143 144
	if (buf[0] == '[')
		{
	    	if (strstr(buf, "Probable"))
			pqg_type = PQG_PQ;
	    	else if (strstr(buf, "Unverifiable"))
			pqg_type = PQG_G;
	    	else if (strstr(buf, "Canonical"))
			pqg_type = PQG_GCANON;
		}
D
Dr. Stephen Henson 已提交
145 146
	if (!parse_line(&keyword, &value, lbuf, buf))
		{
147
		fputs(buf,out);
D
Dr. Stephen Henson 已提交
148 149
		continue;
		}
150
	if (strcmp(keyword, "Num"))
151
		fputs(buf,out);
D
Dr. Stephen Henson 已提交
152
	if(!strcmp(keyword,"[mod"))
153
	    {
D
Dr. Stephen Henson 已提交
154 155 156 157 158
	    if (!parse_mod(value, &dsa2, &L, &N, &md))
		{
		fprintf(stderr, "Mod Parse Error\n");
		exit (1);
		}
159
	    }
160 161
	else if(!strcmp(keyword,"N") 
		|| (!strcmp(keyword, "Num") && pqg_type == PQG_PQ))
D
Dr. Stephen Henson 已提交
162 163 164 165 166 167 168 169 170 171
	    {
	    int n=atoi(value);

	    while(n--)
		{
		DSA *dsa;
		int counter;
		unsigned long h;
		dsa = FIPS_dsa_new();

D
Dr. Stephen Henson 已提交
172 173 174 175 176 177 178 179
		if (!dsa2 && !dsa_builtin_paramgen(dsa, L, N, md,
						NULL, 0, seed,
						&counter, &h, NULL))
			{
			fprintf(stderr, "Parameter Generation error\n");
			exit(1);
			}
		if (dsa2 && dsa_builtin_paramgen2(dsa, L, N, md,
180
						NULL, 0, -1, seed,
D
Dr. Stephen Henson 已提交
181 182 183
						&counter, &h, NULL) <= 0)
			{
			fprintf(stderr, "Parameter Generation error\n");
D
Dr. Stephen Henson 已提交
184
			exit(1);
D
Dr. Stephen Henson 已提交
185 186
			}
 
187 188
		do_bn_print_name(out, "P",dsa->p);
		do_bn_print_name(out, "Q",dsa->q);
189 190 191 192 193 194
		if (!dsa2)
			do_bn_print_name(out, "G",dsa->g);
		OutputValue(dsa2 ? "domain_parameter_seed" : "Seed",
				seed, M_EVP_MD_size(md), out, 0);
		if (!dsa2)
			{
195 196
			fprintf(out, "c = %d" RESP_EOL, counter);
			fprintf(out, "H = %lx" RESP_EOL RESP_EOL,h);
197 198
			}
		else
199
			{
200
			fprintf(out, "counter = %d" RESP_EOL RESP_EOL, counter);
201
			}
202
		FIPS_dsa_free(dsa);
D
Dr. Stephen Henson 已提交
203 204
		}
	    }
205 206 207 208 209 210
	else if(!strcmp(keyword,"P"))
	    p=hex2bn(value);
	else if(!strcmp(keyword,"Q"))
	    q=hex2bn(value);
	else if(!strcmp(keyword,"domain_parameter_seed"))
	    seedlen = hex2bin(value, seed);
211 212 213 214 215 216
	else if(!strcmp(keyword,"firstseed"))
	    seedlen = hex2bin(value, seed);
	else if(!strcmp(keyword,"pseed"))
	    seedlen += hex2bin(value, seed + seedlen);
	else if(!strcmp(keyword,"qseed"))
	    seedlen += hex2bin(value, seed + seedlen);
217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244
	else if(!strcmp(keyword,"index"))
	    {
	    idxlen = hex2bin(value, idtmp);
            if (idxlen != 1)
		{
		fprintf(stderr, "Index value error\n");
		exit (1);
		}
	    idx = idtmp[0];
	    }
	if ((idx >= 0 && pqg_type == PQG_GCANON) || (q && pqg_type == PQG_G))
		{
		DSA *dsa;
		dsa = FIPS_dsa_new();
		dsa->p = p;
		dsa->q = q;
		p = q = NULL;
		if (dsa_builtin_paramgen2(dsa, L, N, md,
						seed, seedlen, idx, NULL,
						NULL, NULL, NULL) <= 0)
			{
			fprintf(stderr, "Parameter Generation error\n");
			exit(1);
			}
		do_bn_print_name(out, "G",dsa->g);
		FIPS_dsa_free(dsa);
		idx = -1;
		}
D
Dr. Stephen Henson 已提交
245 246 247
	}
    }

248
static void pqgver(FILE *in, FILE *out)
D
Dr. Stephen Henson 已提交
249 250 251 252 253
    {
    char buf[1024];
    char lbuf[1024];
    char *keyword, *value;
    BIGNUM *p = NULL, *q = NULL, *g = NULL;
D
Dr. Stephen Henson 已提交
254
    int counter=-1, counter2;
D
Dr. Stephen Henson 已提交
255
    unsigned long h=0, h2;
D
Dr. Stephen Henson 已提交
256
    DSA *dsa=NULL;
257
    int dsa2, L, N, part_test = 0;
258
    const EVP_MD *md = NULL;
259 260
    int seedlen=-1, idxlen, idx = -1;
    unsigned char seed[1024], idtmp[1024];
D
Dr. Stephen Henson 已提交
261

262
    while(fgets(buf,sizeof buf,in) != NULL)
D
Dr. Stephen Henson 已提交
263 264 265
	{
	if (!parse_line(&keyword, &value, lbuf, buf))
		{
266 267 268 269 270
		if (p && q)
			{
			part_test = 1;
			goto partial;
			}
271
		fputs(buf,out);
D
Dr. Stephen Henson 已提交
272 273
		continue;
		}
274
	fputs(buf, out);
D
Dr. Stephen Henson 已提交
275
	if(!strcmp(keyword,"[mod"))
276 277 278 279 280 281 282
	    {
	    if (!parse_mod(value, &dsa2, &L, &N, &md))
		{
		fprintf(stderr, "Mod Parse Error\n");
		exit (1);
		}
	    }
D
Dr. Stephen Henson 已提交
283 284 285 286 287 288
	else if(!strcmp(keyword,"P"))
	    p=hex2bn(value);
	else if(!strcmp(keyword,"Q"))
	    q=hex2bn(value);
	else if(!strcmp(keyword,"G"))
	    g=hex2bn(value);
289 290 291 292 293 294
	else if(!strcmp(keyword,"firstseed"))
	    seedlen = hex2bin(value, seed);
	else if(!strcmp(keyword,"pseed"))
	    seedlen += hex2bin(value, seed + seedlen);
	else if(!strcmp(keyword,"qseed"))
	    seedlen += hex2bin(value, seed + seedlen);
295 296
	else if(!strcmp(keyword,"Seed")
		|| !strcmp(keyword,"domain_parameter_seed"))
D
Dr. Stephen Henson 已提交
297
	    {
298 299
	    seedlen = hex2bin(value, seed);
	    if (!dsa2 && seedlen != 20)
D
Dr. Stephen Henson 已提交
300 301 302 303
		{
		fprintf(stderr, "Seed parse length error\n");
		exit (1);
		}
304 305 306 307 308 309 310 311 312 313 314 315
	    if (idx > 0)
		part_test = 1;
	    }
	else if(!strcmp(keyword,"index"))
	    {
	    idxlen = hex2bin(value, idtmp);
            if (idxlen != 1)
		{
		fprintf(stderr, "Index value error\n");
		exit (1);
		}
	    idx = idtmp[0];
D
Dr. Stephen Henson 已提交
316 317
	    }
	else if(!strcmp(keyword,"c"))
318
	    counter = atoi(buf+4);
319
	partial:
320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340
	if (part_test && idx < 0 && h == 0 && g)
	    {
	    dsa = FIPS_dsa_new();
	    dsa->p = BN_dup(p);
	    dsa->q = BN_dup(q);
	    dsa->g = BN_dup(g);
	    if (dsa_paramgen_check_g(dsa))
		fprintf(out, "Result = P" RESP_EOL);
	    else
		fprintf(out, "Result = F" RESP_EOL);
	    BN_free(p);
	    BN_free(q);
	    BN_free(g);
	    p = NULL;
	    q = NULL;
	    g = NULL;
	    FIPS_dsa_free(dsa);
	    dsa = NULL;
	    part_test = 0;
	    }
	else if(!strcmp(keyword,"H") || part_test)
D
Dr. Stephen Henson 已提交
341
	    {
342 343 344
	    if (!part_test)
	    	h = atoi(value);
	    if (!p || !q || (!g && !part_test))
D
Dr. Stephen Henson 已提交
345 346 347 348 349
		{
		fprintf(stderr, "Parse Error\n");
		exit (1);
		}
	    dsa = FIPS_dsa_new();
350 351 352 353 354
	    if (idx >= 0)
		{
		dsa->p = BN_dup(p);
		dsa->q = BN_dup(q);
		}
355
	    no_err = 1;
356 357 358 359 360 361 362 363
	    if (!dsa2 && !dsa_builtin_paramgen(dsa, L, N, md,
					seed, seedlen, NULL,
					&counter2, &h2, NULL))
			{
			fprintf(stderr, "Parameter Generation error\n");
			exit(1);
			}
	    if (dsa2 && dsa_builtin_paramgen2(dsa, L, N, md,
364
					seed, seedlen, idx, NULL,
365 366 367
					&counter2, &h2, NULL) < 0)
			{
			fprintf(stderr, "Parameter Generation error\n");
D
Dr. Stephen Henson 已提交
368
			exit(1);
369
			}
370
	    no_err = 0;
371 372 373
	    if (idx >= 0)
		{
		if (BN_cmp(dsa->g, g))
374
			fprintf(out, "Result = F" RESP_EOL);
375
		else
376
			fprintf(out, "Result = P" RESP_EOL);
377 378
		}
            else if (BN_cmp(dsa->p, p) || BN_cmp(dsa->q, q) || 
379 380
		(!part_test &&
		((BN_cmp(dsa->g, g) || (counter != counter2) || (h != h2)))))
381
	    	fprintf(out, "Result = F" RESP_EOL);
D
Dr. Stephen Henson 已提交
382
	    else
383
	    	fprintf(out, "Result = P" RESP_EOL);
D
Dr. Stephen Henson 已提交
384 385 386 387 388 389 390 391
	    BN_free(p);
	    BN_free(q);
	    BN_free(g);
	    p = NULL;
	    q = NULL;
	    g = NULL;
	    FIPS_dsa_free(dsa);
	    dsa = NULL;
392 393
	    if (part_test)
		{
394 395
		if (idx == -1)
			fputs(buf,out);
396 397
		part_test = 0;
		}
398
	    idx = -1;
D
Dr. Stephen Henson 已提交
399 400 401 402 403 404 405 406 407
	    }
	}
    }

/* Keypair verification routine. NB: this isn't part of the standard FIPS140-2
 * algorithm tests. It is an additional test to perform sanity checks on the
 * output of the KeyPair test.
 */

408
static int dss_paramcheck(int L, int N, BIGNUM *p, BIGNUM *q, BIGNUM *g,
D
Dr. Stephen Henson 已提交
409 410 411
							BN_CTX *ctx)
    {
    BIGNUM *rem = NULL;
412
    if (BN_num_bits(p) != L)
D
Dr. Stephen Henson 已提交
413
	return 0;
414
    if (BN_num_bits(q) != N)
D
Dr. Stephen Henson 已提交
415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432
	return 0;
    if (BN_is_prime_ex(p, BN_prime_checks, ctx, NULL) != 1)
	return 0;
    if (BN_is_prime_ex(q, BN_prime_checks, ctx, NULL) != 1)
	return 0;
    rem = BN_new();
    if (!BN_mod(rem, p, q, ctx) || !BN_is_one(rem)
    	|| (BN_cmp(g, BN_value_one()) <= 0)
	|| !BN_mod_exp(rem, g, q, p, ctx) || !BN_is_one(rem))
	{
	BN_free(rem);
	return 0;
	}
    /* Todo: check g */
    BN_free(rem);
    return 1;
    }

433
static void keyver(FILE *in, FILE *out)
D
Dr. Stephen Henson 已提交
434 435 436 437 438 439 440
    {
    char buf[1024];
    char lbuf[1024];
    char *keyword, *value;
    BIGNUM *p = NULL, *q = NULL, *g = NULL, *X = NULL, *Y = NULL;
    BIGNUM *Y2;
    BN_CTX *ctx = NULL;
441 442
    int dsa2, L, N;
    int paramcheck = 0;
D
Dr. Stephen Henson 已提交
443 444 445 446

    ctx = BN_CTX_new();
    Y2 = BN_new();

447
    while(fgets(buf,sizeof buf,in) != NULL)
D
Dr. Stephen Henson 已提交
448 449 450
	{
	if (!parse_line(&keyword, &value, lbuf, buf))
		{
451
		fputs(buf,out);
D
Dr. Stephen Henson 已提交
452 453 454 455 456 457 458 459 460 461 462 463 464 465
		continue;
		}
	if(!strcmp(keyword,"[mod"))
	    {
	    if (p)
		BN_free(p);
	    p = NULL;
	    if (q)
		BN_free(q);
	    q = NULL;
	    if (g)
		BN_free(g);
	    g = NULL;
	    paramcheck = 0;
466 467 468 469 470
	    if (!parse_mod(value, &dsa2, &L, &N, NULL))
		{
		fprintf(stderr, "Mod Parse Error\n");
		exit (1);
		}
D
Dr. Stephen Henson 已提交
471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487
	    }
	else if(!strcmp(keyword,"P"))
	    p=hex2bn(value);
	else if(!strcmp(keyword,"Q"))
	    q=hex2bn(value);
	else if(!strcmp(keyword,"G"))
	    g=hex2bn(value);
	else if(!strcmp(keyword,"X"))
	    X=hex2bn(value);
	else if(!strcmp(keyword,"Y"))
	    {
	    Y=hex2bn(value);
	    if (!p || !q || !g || !X || !Y)
		{
		fprintf(stderr, "Parse Error\n");
		exit (1);
		}
488 489 490 491 492
	    do_bn_print_name(out, "P",p);
	    do_bn_print_name(out, "Q",q);
	    do_bn_print_name(out, "G",g);
	    do_bn_print_name(out, "X",X);
	    do_bn_print_name(out, "Y",Y);
D
Dr. Stephen Henson 已提交
493 494
	    if (!paramcheck)
		{
495
		if (dss_paramcheck(L, N, p, q, g, ctx))
D
Dr. Stephen Henson 已提交
496 497 498 499 500
			paramcheck = 1;
		else
			paramcheck = -1;
		}
	    if (paramcheck != 1)
501
	   	fprintf(out, "Result = F" RESP_EOL);
D
Dr. Stephen Henson 已提交
502 503 504
	    else
		{
		if (!BN_mod_exp(Y2, g, X, p, ctx) || BN_cmp(Y2, Y))
505
	    		fprintf(out, "Result = F" RESP_EOL);
D
Dr. Stephen Henson 已提交
506
	        else
507
	    		fprintf(out, "Result = P" RESP_EOL);
D
Dr. Stephen Henson 已提交
508 509 510 511 512 513 514 515 516 517 518 519 520 521 522
		}
	    BN_free(X);
	    BN_free(Y);
	    X = NULL;
	    Y = NULL;
	    }
	}
	if (p)
	    BN_free(p);
	if (q)
	    BN_free(q);
	if (g)
	    BN_free(g);
	if (Y2)
	    BN_free(Y2);
523 524
	if (ctx)
	    BN_CTX_free(ctx);
D
Dr. Stephen Henson 已提交
525 526
    }

527
static void keypair(FILE *in, FILE *out)
D
Dr. Stephen Henson 已提交
528 529 530 531
    {
    char buf[1024];
    char lbuf[1024];
    char *keyword, *value;
532
    int dsa2, L, N;
D
Dr. Stephen Henson 已提交
533

534
    while(fgets(buf,sizeof buf,in) != NULL)
D
Dr. Stephen Henson 已提交
535 536 537 538 539 540
	{
	if (!parse_line(&keyword, &value, lbuf, buf))
		{
		continue;
		}
	if(!strcmp(keyword,"[mod"))
541 542 543 544 545 546
	    {
	    if (!parse_mod(value, &dsa2, &L, &N, NULL))
		{
		fprintf(stderr, "Mod Parse Error\n");
		exit (1);
		}
547
	    fputs(buf,out);
548
	    }
D
Dr. Stephen Henson 已提交
549 550 551 552 553 554
	else if(!strcmp(keyword,"N"))
	    {
	    DSA *dsa;
	    int n=atoi(value);

	    dsa = FIPS_dsa_new();
555 556 557 558 559 560
	    if (!dsa2 && !dsa_builtin_paramgen(dsa, L, N, NULL, NULL, 0,
						NULL, NULL, NULL, NULL))
			{
			fprintf(stderr, "Parameter Generation error\n");
			exit(1);
			}
561
	    if (dsa2 && dsa_builtin_paramgen2(dsa, L, N, NULL, NULL, 0, -1,
562 563 564 565 566
						NULL, NULL, NULL, NULL) <= 0)
			{
			fprintf(stderr, "Parameter Generation error\n");
			exit(1);
			}
567 568 569
	    do_bn_print_name(out, "P",dsa->p);
	    do_bn_print_name(out, "Q",dsa->q);
	    do_bn_print_name(out, "G",dsa->g);
570
	    fputs(RESP_EOL, out);
D
Dr. Stephen Henson 已提交
571 572 573 574 575 576

	    while(n--)
		{
		if (!DSA_generate_key(dsa))
			exit(1);

577 578
		do_bn_print_name(out, "X",dsa->priv_key);
		do_bn_print_name(out, "Y",dsa->pub_key);
579
	    	fputs(RESP_EOL, out);
D
Dr. Stephen Henson 已提交
580
		}
581 582
	    if (dsa)
		FIPS_dsa_free(dsa);
D
Dr. Stephen Henson 已提交
583 584 585 586
	    }
	}
    }

587
static void siggen(FILE *in, FILE *out)
D
Dr. Stephen Henson 已提交
588 589 590 591
    {
    char buf[1024];
    char lbuf[1024];
    char *keyword, *value;
D
Dr. Stephen Henson 已提交
592 593
    int dsa2, L, N;
    const EVP_MD *md = NULL;
D
Dr. Stephen Henson 已提交
594 595
    DSA *dsa=NULL;

596
    while(fgets(buf,sizeof buf,in) != NULL)
D
Dr. Stephen Henson 已提交
597 598 599
	{
	if (!parse_line(&keyword, &value, lbuf, buf))
		{
600
		fputs(buf,out);
D
Dr. Stephen Henson 已提交
601 602
		continue;
		}
603
	fputs(buf,out);
D
Dr. Stephen Henson 已提交
604 605
	if(!strcmp(keyword,"[mod"))
	    {
D
Dr. Stephen Henson 已提交
606 607 608 609 610
	    if (!parse_mod(value, &dsa2, &L, &N, &md))
		{
		fprintf(stderr, "Mod Parse Error\n");
		exit (1);
		}
D
Dr. Stephen Henson 已提交
611 612 613
	    if (dsa)
		FIPS_dsa_free(dsa);
	    dsa = FIPS_dsa_new();
D
Dr. Stephen Henson 已提交
614 615 616 617 618 619
	    if (!dsa2 && !dsa_builtin_paramgen(dsa, L, N, md, NULL, 0,
						NULL, NULL, NULL, NULL))
			{
			fprintf(stderr, "Parameter Generation error\n");
			exit(1);
			}
620
	    if (dsa2 && dsa_builtin_paramgen2(dsa, L, N, md, NULL, 0, -1,
D
Dr. Stephen Henson 已提交
621 622 623 624 625
						NULL, NULL, NULL, NULL) <= 0)
			{
			fprintf(stderr, "Parameter Generation error\n");
			exit(1);
			}
626 627 628
	    do_bn_print_name(out, "P",dsa->p);
	    do_bn_print_name(out, "Q",dsa->q);
	    do_bn_print_name(out, "G",dsa->g);
629
	    fputs(RESP_EOL, out);
D
Dr. Stephen Henson 已提交
630 631 632 633 634 635 636 637 638 639 640
	    }
	else if(!strcmp(keyword,"Msg"))
	    {
	    unsigned char msg[1024];
	    int n;
	    DSA_SIG *sig;

	    n=hex2bin(value,msg);

	    if (!DSA_generate_key(dsa))
		exit(1);
641
	    do_bn_print_name(out, "Y",dsa->pub_key);
D
Dr. Stephen Henson 已提交
642

643
	    sig = FIPS_dsa_sign(dsa, msg, n, md);
D
Dr. Stephen Henson 已提交
644

645 646
	    do_bn_print_name(out, "R",sig->r);
	    do_bn_print_name(out, "S",sig->s);
647
	    fputs(RESP_EOL, out);
648
	    FIPS_dsa_sig_free(sig);
D
Dr. Stephen Henson 已提交
649 650
	    }
	}
651 652
    if (dsa)
	FIPS_dsa_free(dsa);
D
Dr. Stephen Henson 已提交
653 654
    }

655
static void sigver(FILE *in, FILE *out)
D
Dr. Stephen Henson 已提交
656 657 658 659 660 661
    {
    DSA *dsa=NULL;
    char buf[1024];
    char lbuf[1024];
    unsigned char msg[1024];
    char *keyword, *value;
662 663 664
    int n=0;
    int dsa2, L, N;
    const EVP_MD *md = NULL;
D
Dr. Stephen Henson 已提交
665 666 667 668 669
    DSA_SIG sg, *sig = &sg;

    sig->r = NULL;
    sig->s = NULL;

670
    while(fgets(buf,sizeof buf,in) != NULL)
D
Dr. Stephen Henson 已提交
671 672 673
	{
	if (!parse_line(&keyword, &value, lbuf, buf))
		{
674
		fputs(buf,out);
D
Dr. Stephen Henson 已提交
675 676
		continue;
		}
677
	fputs(buf,out);
D
Dr. Stephen Henson 已提交
678 679
	if(!strcmp(keyword,"[mod"))
	    {
680 681 682 683 684 685
	    if (!parse_mod(value, &dsa2, &L, &N, &md))
		{
		fprintf(stderr, "Mod Parse Error\n");
		exit (1);
		}
	    if (dsa)
D
Dr. Stephen Henson 已提交
686
		FIPS_dsa_free(dsa);
687
	    dsa = FIPS_dsa_new();
D
Dr. Stephen Henson 已提交
688 689
	    }
	else if(!strcmp(keyword,"P"))
690
	    do_hex2bn(&dsa->p, value);
D
Dr. Stephen Henson 已提交
691
	else if(!strcmp(keyword,"Q"))
692
	    do_hex2bn(&dsa->q, value);
D
Dr. Stephen Henson 已提交
693
	else if(!strcmp(keyword,"G"))
694
	    do_hex2bn(&dsa->g, value);
D
Dr. Stephen Henson 已提交
695 696 697
	else if(!strcmp(keyword,"Msg"))
	    n=hex2bin(value,msg);
	else if(!strcmp(keyword,"Y"))
698
	    do_hex2bn(&dsa->pub_key, value);
D
Dr. Stephen Henson 已提交
699 700 701 702 703 704
	else if(!strcmp(keyword,"R"))
	    sig->r=hex2bn(value);
	else if(!strcmp(keyword,"S"))
	    {
	    int r;
	    sig->s=hex2bn(value);
D
Dr. Stephen Henson 已提交
705

D
Dr. Stephen Henson 已提交
706
	    no_err = 1;
707
	    r = FIPS_dsa_verify(dsa, msg, n, md, sig);
D
Dr. Stephen Henson 已提交
708
	    no_err = 0;
709 710 711 712 713 714 715 716 717 718
	    if (sig->s)
		{
		BN_free(sig->s);
		sig->s = NULL;
		}
	    if (sig->r)
		{
		BN_free(sig->r);
		sig->r = NULL;
		}
D
Dr. Stephen Henson 已提交
719
	
720
	    fprintf(out, "Result = %c" RESP_EOL RESP_EOL, r == 1 ? 'P' : 'F');
D
Dr. Stephen Henson 已提交
721 722
	    }
	}
723 724
	if (dsa)
	    FIPS_dsa_free(dsa);
D
Dr. Stephen Henson 已提交
725 726
    }

727 728 729 730 731
#ifdef FIPS_ALGVS
int fips_dssvs_main(int argc, char **argv)
#else
int main(int argc, char **argv)
#endif
D
Dr. Stephen Henson 已提交
732
    {
733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754
    FILE *in, *out;
    if (argc == 4)
	{
	in = fopen(argv[2], "r");
	if (!in)
		{
		fprintf(stderr, "Error opening input file\n");
		exit(1);
		}
	out = fopen(argv[3], "w");
	if (!out)
		{
		fprintf(stderr, "Error opening output file\n");
		exit(1);
		}
	}
    else if (argc == 2)
	{
	in = stdin;
	out = stdout;
	}
    else
D
Dr. Stephen Henson 已提交
755
	{
756
	fprintf(stderr,"%s [prime|pqg|pqgver|keypair|keyver|siggen|sigver]\n",argv[0]);
D
Dr. Stephen Henson 已提交
757 758
	exit(1);
	}
759
    fips_algtest_init();
D
Dr. Stephen Henson 已提交
760
    if(!strcmp(argv[1],"prime"))
761
	primes(in, out);
D
Dr. Stephen Henson 已提交
762
    else if(!strcmp(argv[1],"pqg"))
763
	pqg(in, out);
D
Dr. Stephen Henson 已提交
764
    else if(!strcmp(argv[1],"pqgver"))
765
	pqgver(in, out);
D
Dr. Stephen Henson 已提交
766
    else if(!strcmp(argv[1],"keypair"))
767
	keypair(in, out);
D
Dr. Stephen Henson 已提交
768
    else if(!strcmp(argv[1],"keyver"))
769
	keyver(in, out);
D
Dr. Stephen Henson 已提交
770
    else if(!strcmp(argv[1],"siggen"))
771
	siggen(in, out);
D
Dr. Stephen Henson 已提交
772
    else if(!strcmp(argv[1],"sigver"))
773
	sigver(in, out);
D
Dr. Stephen Henson 已提交
774 775 776 777 778 779
    else
	{
	fprintf(stderr,"Don't know how to %s.\n",argv[1]);
	exit(1);
	}

780 781 782 783 784 785
    if (argc == 4)
	{
	fclose(in);
	fclose(out);
	}

D
Dr. Stephen Henson 已提交
786 787 788 789
    return 0;
    }

#endif