1d9e397b599b13d642138480a28c14db7a136bf0Adam Langley/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
2d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * All rights reserved.
3d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *
4d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * This package is an SSL implementation written
5d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * by Eric Young (eay@cryptsoft.com).
6d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * The implementation was written so as to conform with Netscapes SSL.
7d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *
8d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * This library is free for commercial and non-commercial use as long as
9d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * the following conditions are aheared to.  The following conditions
10d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * apply to all code found in this distribution, be it the RC4, RSA,
11d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
12d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * included with this distribution is covered by the same copyright terms
13d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * except that the holder is Tim Hudson (tjh@cryptsoft.com).
14d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *
15d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * Copyright remains Eric Young's, and as such any Copyright notices in
16d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * the code are not to be removed.
17d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * If this package is used in a product, Eric Young should be given attribution
18d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * as the author of the parts of the library used.
19d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * This can be in the form of a textual message at program startup or
20d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * in documentation (online or textual) provided with the package.
21d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *
22d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * Redistribution and use in source and binary forms, with or without
23d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * modification, are permitted provided that the following conditions
24d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * are met:
25d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 1. Redistributions of source code must retain the copyright
26d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *    notice, this list of conditions and the following disclaimer.
27d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 2. Redistributions in binary form must reproduce the above copyright
28d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *    notice, this list of conditions and the following disclaimer in the
29d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *    documentation and/or other materials provided with the distribution.
30d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 3. All advertising materials mentioning features or use of this software
31d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *    must display the following acknowledgement:
32d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *    "This product includes cryptographic software written by
33d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *     Eric Young (eay@cryptsoft.com)"
34d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *    The word 'cryptographic' can be left out if the rouines from the library
35d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *    being used are not cryptographic related :-).
36d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 4. If you include any Windows specific code (or a derivative thereof) from
37d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *    the apps directory (application code) you must include an acknowledgement:
38d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
39d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *
40d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
41d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
42d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
43d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
44d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
45d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
46d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
48d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
49d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
50d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * SUCH DAMAGE.
51d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *
52d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * The licence and distribution terms for any publically available version or
53d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * derivative of this code cannot be changed.  i.e. this code cannot simply be
54d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * copied and put under another distribution licence
55d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * [including the GNU Public Licence.]
56d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *
57d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * The DSS routines are based on patches supplied by
58d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * Steven Schoch <schoch@sheba.arc.nasa.gov>. */
59d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
60d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#include <openssl/dsa.h>
61d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
6269939df2891f62f7f00ff2ac275f1cd81a67454cRobert Sloan#include <stdio.h>
63d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#include <string.h>
64d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
65f31229be918beb36153746ca75f900569b57e30fDavid Benjamin#include <gtest/gtest.h>
66f31229be918beb36153746ca75f900569b57e30fDavid Benjamin
67d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#include <openssl/bn.h>
68d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#include <openssl/crypto.h>
69d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#include <openssl/err.h>
70d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
7169939df2891f62f7f00ff2ac275f1cd81a67454cRobert Sloan#include "../internal.h"
72d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
73d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
748f860b133896bf655e4342ecefe692d52df81d48Robert Sloan// The following values are taken from the updated Appendix 5 to FIPS PUB 186
758f860b133896bf655e4342ecefe692d52df81d48Robert Sloan// and also appear in Appendix 5 to FIPS PUB 186-1.
76d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
77d9e397b599b13d642138480a28c14db7a136bf0Adam Langleystatic const uint8_t seed[20] = {
78d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    0xd5, 0x01, 0x4e, 0x4b, 0x60, 0xef, 0x2b, 0xa8, 0xb6, 0x21, 0x1b,
79d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    0x40, 0x62, 0xba, 0x32, 0x24, 0xe0, 0x42, 0x7d, 0xd3,
80d9e397b599b13d642138480a28c14db7a136bf0Adam Langley};
81d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
82d9e397b599b13d642138480a28c14db7a136bf0Adam Langleystatic const uint8_t fips_p[] = {
83d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    0x8d, 0xf2, 0xa4, 0x94, 0x49, 0x22, 0x76, 0xaa, 0x3d, 0x25, 0x75,
84d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    0x9b, 0xb0, 0x68, 0x69, 0xcb, 0xea, 0xc0, 0xd8, 0x3a, 0xfb, 0x8d,
85d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    0x0c, 0xf7, 0xcb, 0xb8, 0x32, 0x4f, 0x0d, 0x78, 0x82, 0xe5, 0xd0,
86d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    0x76, 0x2f, 0xc5, 0xb7, 0x21, 0x0e, 0xaf, 0xc2, 0xe9, 0xad, 0xac,
87d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    0x32, 0xab, 0x7a, 0xac, 0x49, 0x69, 0x3d, 0xfb, 0xf8, 0x37, 0x24,
88d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    0xc2, 0xec, 0x07, 0x36, 0xee, 0x31, 0xc8, 0x02, 0x91,
89d9e397b599b13d642138480a28c14db7a136bf0Adam Langley};
90d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
91d9e397b599b13d642138480a28c14db7a136bf0Adam Langleystatic const uint8_t fips_q[] = {
92d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    0xc7, 0x73, 0x21, 0x8c, 0x73, 0x7e, 0xc8, 0xee, 0x99, 0x3b, 0x4f,
93d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    0x2d, 0xed, 0x30, 0xf4, 0x8e, 0xda, 0xce, 0x91, 0x5f,
94d9e397b599b13d642138480a28c14db7a136bf0Adam Langley};
95d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
96d9e397b599b13d642138480a28c14db7a136bf0Adam Langleystatic const uint8_t fips_g[] = {
97d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    0x62, 0x6d, 0x02, 0x78, 0x39, 0xea, 0x0a, 0x13, 0x41, 0x31, 0x63,
98d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    0xa5, 0x5b, 0x4c, 0xb5, 0x00, 0x29, 0x9d, 0x55, 0x22, 0x95, 0x6c,
99d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    0xef, 0xcb, 0x3b, 0xff, 0x10, 0xf3, 0x99, 0xce, 0x2c, 0x2e, 0x71,
100d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    0xcb, 0x9d, 0xe5, 0xfa, 0x24, 0xba, 0xbf, 0x58, 0xe5, 0xb7, 0x95,
101d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    0x21, 0x92, 0x5c, 0x9c, 0xc4, 0x2e, 0x9f, 0x6f, 0x46, 0x4b, 0x08,
102d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    0x8c, 0xc5, 0x72, 0xaf, 0x53, 0xe6, 0xd7, 0x88, 0x02,
103d9e397b599b13d642138480a28c14db7a136bf0Adam Langley};
104d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
105d9e397b599b13d642138480a28c14db7a136bf0Adam Langleystatic const uint8_t fips_x[] = {
106d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    0x20, 0x70, 0xb3, 0x22, 0x3d, 0xba, 0x37, 0x2f, 0xde, 0x1c, 0x0f,
107d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    0xfc, 0x7b, 0x2e, 0x3b, 0x49, 0x8b, 0x26, 0x06, 0x14,
108d9e397b599b13d642138480a28c14db7a136bf0Adam Langley};
109d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
110d9e397b599b13d642138480a28c14db7a136bf0Adam Langleystatic const uint8_t fips_y[] = {
111d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    0x19, 0x13, 0x18, 0x71, 0xd7, 0x5b, 0x16, 0x12, 0xa8, 0x19, 0xf2,
112d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    0x9d, 0x78, 0xd1, 0xb0, 0xd7, 0x34, 0x6f, 0x7a, 0xa7, 0x7b, 0xb6,
113d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    0x2a, 0x85, 0x9b, 0xfd, 0x6c, 0x56, 0x75, 0xda, 0x9d, 0x21, 0x2d,
114d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    0x3a, 0x36, 0xef, 0x16, 0x72, 0xef, 0x66, 0x0b, 0x8c, 0x7c, 0x25,
115d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    0x5c, 0xc0, 0xec, 0x74, 0x85, 0x8f, 0xba, 0x33, 0xf4, 0x4c, 0x06,
116d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    0x69, 0x96, 0x30, 0xa7, 0x6b, 0x03, 0x0e, 0xe3, 0x33,
117d9e397b599b13d642138480a28c14db7a136bf0Adam Langley};
118d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
119d9e397b599b13d642138480a28c14db7a136bf0Adam Langleystatic const uint8_t fips_digest[] = {
120d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    0xa9, 0x99, 0x3e, 0x36, 0x47, 0x06, 0x81, 0x6a, 0xba, 0x3e, 0x25,
121d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    0x71, 0x78, 0x50, 0xc2, 0x6c, 0x9c, 0xd0, 0xd8, 0x9d,
122d9e397b599b13d642138480a28c14db7a136bf0Adam Langley};
123d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
1248f860b133896bf655e4342ecefe692d52df81d48Robert Sloan// fips_sig is a DER-encoded version of the r and s values in FIPS PUB 186-1.
125d9e397b599b13d642138480a28c14db7a136bf0Adam Langleystatic const uint8_t fips_sig[] = {
126d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    0x30, 0x2d, 0x02, 0x15, 0x00, 0x8b, 0xac, 0x1a, 0xb6, 0x64, 0x10,
127d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    0x43, 0x5c, 0xb7, 0x18, 0x1f, 0x95, 0xb1, 0x6a, 0xb9, 0x7c, 0x92,
128d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    0xb3, 0x41, 0xc0, 0x02, 0x14, 0x41, 0xe2, 0x34, 0x5f, 0x1f, 0x56,
129d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    0xdf, 0x24, 0x58, 0xf4, 0x26, 0xd1, 0x55, 0xb4, 0xba, 0x2d, 0xb6,
130d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    0xdc, 0xd8, 0xc8,
131d9e397b599b13d642138480a28c14db7a136bf0Adam Langley};
132d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
1338f860b133896bf655e4342ecefe692d52df81d48Robert Sloan// fips_sig_negative is fips_sig with r encoded as a negative number.
134d9e397b599b13d642138480a28c14db7a136bf0Adam Langleystatic const uint8_t fips_sig_negative[] = {
135d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    0x30, 0x2c, 0x02, 0x14, 0x8b, 0xac, 0x1a, 0xb6, 0x64, 0x10, 0x43,
136d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    0x5c, 0xb7, 0x18, 0x1f, 0x95, 0xb1, 0x6a, 0xb9, 0x7c, 0x92, 0xb3,
137d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    0x41, 0xc0, 0x02, 0x14, 0x41, 0xe2, 0x34, 0x5f, 0x1f, 0x56, 0xdf,
138d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    0x24, 0x58, 0xf4, 0x26, 0xd1, 0x55, 0xb4, 0xba, 0x2d, 0xb6, 0xdc,
139d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    0xd8, 0xc8,
140d9e397b599b13d642138480a28c14db7a136bf0Adam Langley};
141d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
1428f860b133896bf655e4342ecefe692d52df81d48Robert Sloan// fip_sig_extra is fips_sig with trailing data.
143d9e397b599b13d642138480a28c14db7a136bf0Adam Langleystatic const uint8_t fips_sig_extra[] = {
144d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    0x30, 0x2d, 0x02, 0x15, 0x00, 0x8b, 0xac, 0x1a, 0xb6, 0x64, 0x10,
145d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    0x43, 0x5c, 0xb7, 0x18, 0x1f, 0x95, 0xb1, 0x6a, 0xb9, 0x7c, 0x92,
146d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    0xb3, 0x41, 0xc0, 0x02, 0x14, 0x41, 0xe2, 0x34, 0x5f, 0x1f, 0x56,
147d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    0xdf, 0x24, 0x58, 0xf4, 0x26, 0xd1, 0x55, 0xb4, 0xba, 0x2d, 0xb6,
148d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    0xdc, 0xd8, 0xc8, 0x00,
149d9e397b599b13d642138480a28c14db7a136bf0Adam Langley};
150d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
1518f860b133896bf655e4342ecefe692d52df81d48Robert Sloan// fips_sig_lengths is fips_sig with a non-minimally encoded length.
152d9e397b599b13d642138480a28c14db7a136bf0Adam Langleystatic const uint8_t fips_sig_bad_length[] = {
153d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    0x30, 0x81, 0x2d, 0x02, 0x15, 0x00, 0x8b, 0xac, 0x1a, 0xb6, 0x64,
154d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    0x10, 0x43, 0x5c, 0xb7, 0x18, 0x1f, 0x95, 0xb1, 0x6a, 0xb9, 0x7c,
155d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    0x92, 0xb3, 0x41, 0xc0, 0x02, 0x14, 0x41, 0xe2, 0x34, 0x5f, 0x1f,
156d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    0x56, 0xdf, 0x24, 0x58, 0xf4, 0x26, 0xd1, 0x55, 0xb4, 0xba, 0x2d,
157d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    0xb6, 0xdc, 0xd8, 0xc8, 0x00,
158d9e397b599b13d642138480a28c14db7a136bf0Adam Langley};
159d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
1608f860b133896bf655e4342ecefe692d52df81d48Robert Sloan// fips_sig_bad_r is fips_sig with a bad r value.
161d9e397b599b13d642138480a28c14db7a136bf0Adam Langleystatic const uint8_t fips_sig_bad_r[] = {
162d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    0x30, 0x2d, 0x02, 0x15, 0x00, 0x8c, 0xac, 0x1a, 0xb6, 0x64, 0x10,
163d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    0x43, 0x5c, 0xb7, 0x18, 0x1f, 0x95, 0xb1, 0x6a, 0xb9, 0x7c, 0x92,
164d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    0xb3, 0x41, 0xc0, 0x02, 0x14, 0x41, 0xe2, 0x34, 0x5f, 0x1f, 0x56,
165d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    0xdf, 0x24, 0x58, 0xf4, 0x26, 0xd1, 0x55, 0xb4, 0xba, 0x2d, 0xb6,
166d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    0xdc, 0xd8, 0xc8,
167d9e397b599b13d642138480a28c14db7a136bf0Adam Langley};
168d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
16969939df2891f62f7f00ff2ac275f1cd81a67454cRobert Sloanstatic bssl::UniquePtr<DSA> GetFIPSDSA(void) {
17069939df2891f62f7f00ff2ac275f1cd81a67454cRobert Sloan  bssl::UniquePtr<DSA>  dsa(DSA_new());
171d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  if (!dsa) {
17269939df2891f62f7f00ff2ac275f1cd81a67454cRobert Sloan    return nullptr;
173d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
17469939df2891f62f7f00ff2ac275f1cd81a67454cRobert Sloan  dsa->p = BN_bin2bn(fips_p, sizeof(fips_p), nullptr);
17569939df2891f62f7f00ff2ac275f1cd81a67454cRobert Sloan  dsa->q = BN_bin2bn(fips_q, sizeof(fips_q), nullptr);
17669939df2891f62f7f00ff2ac275f1cd81a67454cRobert Sloan  dsa->g = BN_bin2bn(fips_g, sizeof(fips_g), nullptr);
17769939df2891f62f7f00ff2ac275f1cd81a67454cRobert Sloan  dsa->pub_key = BN_bin2bn(fips_y, sizeof(fips_y), nullptr);
17869939df2891f62f7f00ff2ac275f1cd81a67454cRobert Sloan  dsa->priv_key = BN_bin2bn(fips_x, sizeof(fips_x), nullptr);
17969939df2891f62f7f00ff2ac275f1cd81a67454cRobert Sloan  if (dsa->p == nullptr || dsa->q == nullptr || dsa->g == nullptr ||
18069939df2891f62f7f00ff2ac275f1cd81a67454cRobert Sloan      dsa->pub_key == nullptr || dsa->priv_key == nullptr) {
18169939df2891f62f7f00ff2ac275f1cd81a67454cRobert Sloan    return nullptr;
182d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
183d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  return dsa;
184d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
185d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
18669939df2891f62f7f00ff2ac275f1cd81a67454cRobert Sloanstruct GenerateContext {
18769939df2891f62f7f00ff2ac275f1cd81a67454cRobert Sloan  FILE *out = nullptr;
18869939df2891f62f7f00ff2ac275f1cd81a67454cRobert Sloan  int ok = 0;
18969939df2891f62f7f00ff2ac275f1cd81a67454cRobert Sloan  int num = 0;
19069939df2891f62f7f00ff2ac275f1cd81a67454cRobert Sloan};
19169939df2891f62f7f00ff2ac275f1cd81a67454cRobert Sloan
19269939df2891f62f7f00ff2ac275f1cd81a67454cRobert Sloanstatic int GenerateCallback(int p, int n, BN_GENCB *arg) {
19369939df2891f62f7f00ff2ac275f1cd81a67454cRobert Sloan  GenerateContext *ctx = reinterpret_cast<GenerateContext *>(arg->arg);
19469939df2891f62f7f00ff2ac275f1cd81a67454cRobert Sloan  char c = '*';
19569939df2891f62f7f00ff2ac275f1cd81a67454cRobert Sloan  switch (p) {
19669939df2891f62f7f00ff2ac275f1cd81a67454cRobert Sloan    case 0:
19769939df2891f62f7f00ff2ac275f1cd81a67454cRobert Sloan      c = '.';
19869939df2891f62f7f00ff2ac275f1cd81a67454cRobert Sloan      ctx->num++;
19969939df2891f62f7f00ff2ac275f1cd81a67454cRobert Sloan      break;
20069939df2891f62f7f00ff2ac275f1cd81a67454cRobert Sloan    case 1:
20169939df2891f62f7f00ff2ac275f1cd81a67454cRobert Sloan      c = '+';
20269939df2891f62f7f00ff2ac275f1cd81a67454cRobert Sloan      break;
20369939df2891f62f7f00ff2ac275f1cd81a67454cRobert Sloan    case 2:
20469939df2891f62f7f00ff2ac275f1cd81a67454cRobert Sloan      c = '*';
20569939df2891f62f7f00ff2ac275f1cd81a67454cRobert Sloan      ctx->ok++;
20669939df2891f62f7f00ff2ac275f1cd81a67454cRobert Sloan      break;
20769939df2891f62f7f00ff2ac275f1cd81a67454cRobert Sloan    case 3:
20869939df2891f62f7f00ff2ac275f1cd81a67454cRobert Sloan      c = '\n';
20969939df2891f62f7f00ff2ac275f1cd81a67454cRobert Sloan  }
21069939df2891f62f7f00ff2ac275f1cd81a67454cRobert Sloan  fputc(c, ctx->out);
21169939df2891f62f7f00ff2ac275f1cd81a67454cRobert Sloan  fflush(ctx->out);
21269939df2891f62f7f00ff2ac275f1cd81a67454cRobert Sloan  if (!ctx->ok && p == 0 && ctx->num > 1) {
21369939df2891f62f7f00ff2ac275f1cd81a67454cRobert Sloan    fprintf(stderr, "error in dsatest\n");
21469939df2891f62f7f00ff2ac275f1cd81a67454cRobert Sloan    return 0;
21569939df2891f62f7f00ff2ac275f1cd81a67454cRobert Sloan  }
21669939df2891f62f7f00ff2ac275f1cd81a67454cRobert Sloan  return 1;
21769939df2891f62f7f00ff2ac275f1cd81a67454cRobert Sloan}
21869939df2891f62f7f00ff2ac275f1cd81a67454cRobert Sloan
21969939df2891f62f7f00ff2ac275f1cd81a67454cRobert Sloanstatic int TestGenerate(FILE *out) {
220d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  BN_GENCB cb;
22169939df2891f62f7f00ff2ac275f1cd81a67454cRobert Sloan  int counter, i, j;
222d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  uint8_t buf[256];
223d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  unsigned long h;
224d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  uint8_t sig[256];
225d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  unsigned int siglen;
226d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
227e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  fprintf(out, "test generation of DSA parameters\n");
228d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
22969939df2891f62f7f00ff2ac275f1cd81a67454cRobert Sloan  GenerateContext ctx;
23069939df2891f62f7f00ff2ac275f1cd81a67454cRobert Sloan  ctx.out = out;
23169939df2891f62f7f00ff2ac275f1cd81a67454cRobert Sloan  BN_GENCB_set(&cb, GenerateCallback, &ctx);
23269939df2891f62f7f00ff2ac275f1cd81a67454cRobert Sloan  bssl::UniquePtr<DSA> dsa(DSA_new());
23369939df2891f62f7f00ff2ac275f1cd81a67454cRobert Sloan  if (!dsa ||
23469939df2891f62f7f00ff2ac275f1cd81a67454cRobert Sloan      !DSA_generate_parameters_ex(dsa.get(), 512, seed, 20, &counter, &h,
23569939df2891f62f7f00ff2ac275f1cd81a67454cRobert Sloan                                  &cb)) {
23669939df2891f62f7f00ff2ac275f1cd81a67454cRobert Sloan    return false;
237d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
238d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
239e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  fprintf(out, "seed\n");
240d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  for (i = 0; i < 20; i += 4) {
241e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley    fprintf(out, "%02X%02X%02X%02X ", seed[i], seed[i + 1], seed[i + 2],
242e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley            seed[i + 3]);
243d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
244e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  fprintf(out, "\ncounter=%d h=%ld\n", counter, h);
245d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
246d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  if (counter != 105) {
247e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley    fprintf(stderr, "counter should be 105\n");
24869939df2891f62f7f00ff2ac275f1cd81a67454cRobert Sloan    return false;
249d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
250d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  if (h != 2) {
251e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley    fprintf(stderr, "h should be 2\n");
25269939df2891f62f7f00ff2ac275f1cd81a67454cRobert Sloan    return false;
253d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
254d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
255d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  i = BN_bn2bin(dsa->q, buf);
256d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  j = sizeof(fips_q);
25769939df2891f62f7f00ff2ac275f1cd81a67454cRobert Sloan  if (i != j || OPENSSL_memcmp(buf, fips_q, i) != 0) {
258e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley    fprintf(stderr, "q value is wrong\n");
25969939df2891f62f7f00ff2ac275f1cd81a67454cRobert Sloan    return false;
260d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
261d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
262d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  i = BN_bn2bin(dsa->p, buf);
263d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  j = sizeof(fips_p);
26469939df2891f62f7f00ff2ac275f1cd81a67454cRobert Sloan  if (i != j || OPENSSL_memcmp(buf, fips_p, i) != 0) {
265e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley    fprintf(stderr, "p value is wrong\n");
26669939df2891f62f7f00ff2ac275f1cd81a67454cRobert Sloan    return false;
267d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
268d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
269d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  i = BN_bn2bin(dsa->g, buf);
270d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  j = sizeof(fips_g);
27169939df2891f62f7f00ff2ac275f1cd81a67454cRobert Sloan  if (i != j || OPENSSL_memcmp(buf, fips_g, i) != 0) {
272e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley    fprintf(stderr, "g value is wrong\n");
27369939df2891f62f7f00ff2ac275f1cd81a67454cRobert Sloan    return false;
274d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
275d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
27669939df2891f62f7f00ff2ac275f1cd81a67454cRobert Sloan  if (!DSA_generate_key(dsa.get()) ||
27769939df2891f62f7f00ff2ac275f1cd81a67454cRobert Sloan      !DSA_sign(0, fips_digest, sizeof(fips_digest), sig, &siglen, dsa.get())) {
27869939df2891f62f7f00ff2ac275f1cd81a67454cRobert Sloan    return false;
27953b272a2813a0b11f107d77100ff8805ada8fbd2Adam Langley  }
28069939df2891f62f7f00ff2ac275f1cd81a67454cRobert Sloan  if (DSA_verify(0, fips_digest, sizeof(fips_digest), sig, siglen, dsa.get()) !=
28169939df2891f62f7f00ff2ac275f1cd81a67454cRobert Sloan      1) {
282e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley    fprintf(stderr, "verification failure\n");
28369939df2891f62f7f00ff2ac275f1cd81a67454cRobert Sloan    return false;
284d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
285d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
28669939df2891f62f7f00ff2ac275f1cd81a67454cRobert Sloan  return true;
287d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
288d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
28969939df2891f62f7f00ff2ac275f1cd81a67454cRobert Sloanstatic bool TestVerify(const uint8_t *sig, size_t sig_len, int expect) {
29069939df2891f62f7f00ff2ac275f1cd81a67454cRobert Sloan  bssl::UniquePtr<DSA> dsa = GetFIPSDSA();
29169939df2891f62f7f00ff2ac275f1cd81a67454cRobert Sloan  if (!dsa) {
29269939df2891f62f7f00ff2ac275f1cd81a67454cRobert Sloan    return false;
293d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
294d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
29569939df2891f62f7f00ff2ac275f1cd81a67454cRobert Sloan  int ret =
29669939df2891f62f7f00ff2ac275f1cd81a67454cRobert Sloan      DSA_verify(0, fips_digest, sizeof(fips_digest), sig, sig_len, dsa.get());
297d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  if (ret != expect) {
298e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley    fprintf(stderr, "DSA_verify returned %d, want %d\n", ret, expect);
29969939df2891f62f7f00ff2ac275f1cd81a67454cRobert Sloan    return false;
300d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
301d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
3028f860b133896bf655e4342ecefe692d52df81d48Robert Sloan  // Clear any errors from a test with expected failure.
30369939df2891f62f7f00ff2ac275f1cd81a67454cRobert Sloan  ERR_clear_error();
30469939df2891f62f7f00ff2ac275f1cd81a67454cRobert Sloan  return true;
305d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
306d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
307f31229be918beb36153746ca75f900569b57e30fDavid Benjamin// TODO(davidben): Convert this file to GTest properly.
308f31229be918beb36153746ca75f900569b57e30fDavid BenjaminTEST(DSATest, AllTests) {
30969939df2891f62f7f00ff2ac275f1cd81a67454cRobert Sloan  if (!TestGenerate(stdout) ||
31069939df2891f62f7f00ff2ac275f1cd81a67454cRobert Sloan      !TestVerify(fips_sig, sizeof(fips_sig), 1) ||
31169939df2891f62f7f00ff2ac275f1cd81a67454cRobert Sloan      !TestVerify(fips_sig_negative, sizeof(fips_sig_negative), -1) ||
31269939df2891f62f7f00ff2ac275f1cd81a67454cRobert Sloan      !TestVerify(fips_sig_extra, sizeof(fips_sig_extra), -1) ||
31369939df2891f62f7f00ff2ac275f1cd81a67454cRobert Sloan      !TestVerify(fips_sig_bad_length, sizeof(fips_sig_bad_length), -1) ||
31469939df2891f62f7f00ff2ac275f1cd81a67454cRobert Sloan      !TestVerify(fips_sig_bad_r, sizeof(fips_sig_bad_r), 0)) {
315f31229be918beb36153746ca75f900569b57e30fDavid Benjamin    ADD_FAILURE() << "Tests failed";
316d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
317d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
318