blob: 295a7fd10453ba4498eace9750a0b25d765a54ee [file] [log] [blame]
Adam Langley95c29f32014-06-20 12:00:00 -07001/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
2 * All rights reserved.
3 *
4 * This package is an SSL implementation written
5 * by Eric Young (eay@cryptsoft.com).
6 * The implementation was written so as to conform with Netscapes SSL.
7 *
8 * This library is free for commercial and non-commercial use as long as
9 * the following conditions are aheared to. The following conditions
10 * apply to all code found in this distribution, be it the RC4, RSA,
11 * lhash, DES, etc., code; not just the SSL code. The SSL documentation
12 * included with this distribution is covered by the same copyright terms
13 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
14 *
15 * Copyright remains Eric Young's, and as such any Copyright notices in
16 * the code are not to be removed.
17 * If this package is used in a product, Eric Young should be given attribution
18 * as the author of the parts of the library used.
19 * This can be in the form of a textual message at program startup or
20 * in documentation (online or textual) provided with the package.
21 *
22 * Redistribution and use in source and binary forms, with or without
23 * modification, are permitted provided that the following conditions
24 * are met:
25 * 1. Redistributions of source code must retain the copyright
26 * notice, this list of conditions and the following disclaimer.
27 * 2. Redistributions in binary form must reproduce the above copyright
28 * notice, this list of conditions and the following disclaimer in the
29 * documentation and/or other materials provided with the distribution.
30 * 3. All advertising materials mentioning features or use of this software
31 * must display the following acknowledgement:
32 * "This product includes cryptographic software written by
33 * Eric Young (eay@cryptsoft.com)"
34 * The word 'cryptographic' can be left out if the rouines from the library
35 * being used are not cryptographic related :-).
36 * 4. If you include any Windows specific code (or a derivative thereof) from
37 * the apps directory (application code) you must include an acknowledgement:
38 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
39 *
40 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
41 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
42 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
43 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
44 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
45 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
46 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
48 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
49 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
50 * SUCH DAMAGE.
51 *
52 * The licence and distribution terms for any publically available version or
53 * derivative of this code cannot be changed. i.e. this code cannot simply be
54 * copied and put under another distribution licence
55 * [including the GNU Public Licence.]
56 *
57 * The DSS routines are based on patches supplied by
58 * Steven Schoch <schoch@sheba.arc.nasa.gov>. */
59
60#include <openssl/dsa.h>
61
David Benjamind17d1da2016-12-21 22:16:43 -050062#include <stdio.h>
Adam Langley2b2d66d2015-01-30 17:08:37 -080063#include <string.h>
64
David Benjamin96628432017-01-19 19:05:47 -050065#include <gtest/gtest.h>
66
Adam Langley95c29f32014-06-20 12:00:00 -070067#include <openssl/bn.h>
David Benjamina70c75c2014-09-11 19:11:15 -040068#include <openssl/crypto.h>
David Benjamin95e18c52015-01-10 23:37:17 -050069#include <openssl/err.h>
Adam Langley95c29f32014-06-20 12:00:00 -070070
David Benjamin17cf2cb2016-12-13 01:07:13 -050071#include "../internal.h"
72
Adam Langley95c29f32014-06-20 12:00:00 -070073
David Benjamin808f8322017-08-18 14:06:02 -040074// The following values are taken from the updated Appendix 5 to FIPS PUB 186
75// and also appear in Appendix 5 to FIPS PUB 186-1.
Adam Langley95c29f32014-06-20 12:00:00 -070076
David Benjamin95e18c52015-01-10 23:37:17 -050077static const uint8_t seed[20] = {
78 0xd5, 0x01, 0x4e, 0x4b, 0x60, 0xef, 0x2b, 0xa8, 0xb6, 0x21, 0x1b,
79 0x40, 0x62, 0xba, 0x32, 0x24, 0xe0, 0x42, 0x7d, 0xd3,
80};
81
82static const uint8_t fips_p[] = {
Adam Langley95c29f32014-06-20 12:00:00 -070083 0x8d, 0xf2, 0xa4, 0x94, 0x49, 0x22, 0x76, 0xaa, 0x3d, 0x25, 0x75,
84 0x9b, 0xb0, 0x68, 0x69, 0xcb, 0xea, 0xc0, 0xd8, 0x3a, 0xfb, 0x8d,
85 0x0c, 0xf7, 0xcb, 0xb8, 0x32, 0x4f, 0x0d, 0x78, 0x82, 0xe5, 0xd0,
86 0x76, 0x2f, 0xc5, 0xb7, 0x21, 0x0e, 0xaf, 0xc2, 0xe9, 0xad, 0xac,
87 0x32, 0xab, 0x7a, 0xac, 0x49, 0x69, 0x3d, 0xfb, 0xf8, 0x37, 0x24,
David Benjamin95e18c52015-01-10 23:37:17 -050088 0xc2, 0xec, 0x07, 0x36, 0xee, 0x31, 0xc8, 0x02, 0x91,
89};
Adam Langley95c29f32014-06-20 12:00:00 -070090
David Benjamin95e18c52015-01-10 23:37:17 -050091static const uint8_t fips_q[] = {
92 0xc7, 0x73, 0x21, 0x8c, 0x73, 0x7e, 0xc8, 0xee, 0x99, 0x3b, 0x4f,
93 0x2d, 0xed, 0x30, 0xf4, 0x8e, 0xda, 0xce, 0x91, 0x5f,
94};
Adam Langley95c29f32014-06-20 12:00:00 -070095
David Benjamin95e18c52015-01-10 23:37:17 -050096static const uint8_t fips_g[] = {
Adam Langley95c29f32014-06-20 12:00:00 -070097 0x62, 0x6d, 0x02, 0x78, 0x39, 0xea, 0x0a, 0x13, 0x41, 0x31, 0x63,
98 0xa5, 0x5b, 0x4c, 0xb5, 0x00, 0x29, 0x9d, 0x55, 0x22, 0x95, 0x6c,
99 0xef, 0xcb, 0x3b, 0xff, 0x10, 0xf3, 0x99, 0xce, 0x2c, 0x2e, 0x71,
100 0xcb, 0x9d, 0xe5, 0xfa, 0x24, 0xba, 0xbf, 0x58, 0xe5, 0xb7, 0x95,
101 0x21, 0x92, 0x5c, 0x9c, 0xc4, 0x2e, 0x9f, 0x6f, 0x46, 0x4b, 0x08,
David Benjamin95e18c52015-01-10 23:37:17 -0500102 0x8c, 0xc5, 0x72, 0xaf, 0x53, 0xe6, 0xd7, 0x88, 0x02,
103};
Adam Langley95c29f32014-06-20 12:00:00 -0700104
David Benjamin95e18c52015-01-10 23:37:17 -0500105static const uint8_t fips_x[] = {
106 0x20, 0x70, 0xb3, 0x22, 0x3d, 0xba, 0x37, 0x2f, 0xde, 0x1c, 0x0f,
107 0xfc, 0x7b, 0x2e, 0x3b, 0x49, 0x8b, 0x26, 0x06, 0x14,
108};
109
110static const uint8_t fips_y[] = {
111 0x19, 0x13, 0x18, 0x71, 0xd7, 0x5b, 0x16, 0x12, 0xa8, 0x19, 0xf2,
112 0x9d, 0x78, 0xd1, 0xb0, 0xd7, 0x34, 0x6f, 0x7a, 0xa7, 0x7b, 0xb6,
113 0x2a, 0x85, 0x9b, 0xfd, 0x6c, 0x56, 0x75, 0xda, 0x9d, 0x21, 0x2d,
114 0x3a, 0x36, 0xef, 0x16, 0x72, 0xef, 0x66, 0x0b, 0x8c, 0x7c, 0x25,
115 0x5c, 0xc0, 0xec, 0x74, 0x85, 0x8f, 0xba, 0x33, 0xf4, 0x4c, 0x06,
116 0x69, 0x96, 0x30, 0xa7, 0x6b, 0x03, 0x0e, 0xe3, 0x33,
117};
118
119static const uint8_t fips_digest[] = {
120 0xa9, 0x99, 0x3e, 0x36, 0x47, 0x06, 0x81, 0x6a, 0xba, 0x3e, 0x25,
121 0x71, 0x78, 0x50, 0xc2, 0x6c, 0x9c, 0xd0, 0xd8, 0x9d,
122};
123
David Benjamin808f8322017-08-18 14:06:02 -0400124// fips_sig is a DER-encoded version of the r and s values in FIPS PUB 186-1.
David Benjamin95e18c52015-01-10 23:37:17 -0500125static const uint8_t fips_sig[] = {
126 0x30, 0x2d, 0x02, 0x15, 0x00, 0x8b, 0xac, 0x1a, 0xb6, 0x64, 0x10,
127 0x43, 0x5c, 0xb7, 0x18, 0x1f, 0x95, 0xb1, 0x6a, 0xb9, 0x7c, 0x92,
128 0xb3, 0x41, 0xc0, 0x02, 0x14, 0x41, 0xe2, 0x34, 0x5f, 0x1f, 0x56,
129 0xdf, 0x24, 0x58, 0xf4, 0x26, 0xd1, 0x55, 0xb4, 0xba, 0x2d, 0xb6,
130 0xdc, 0xd8, 0xc8,
131};
132
David Benjamin808f8322017-08-18 14:06:02 -0400133// fips_sig_negative is fips_sig with r encoded as a negative number.
David Benjamin95e18c52015-01-10 23:37:17 -0500134static const uint8_t fips_sig_negative[] = {
135 0x30, 0x2c, 0x02, 0x14, 0x8b, 0xac, 0x1a, 0xb6, 0x64, 0x10, 0x43,
136 0x5c, 0xb7, 0x18, 0x1f, 0x95, 0xb1, 0x6a, 0xb9, 0x7c, 0x92, 0xb3,
137 0x41, 0xc0, 0x02, 0x14, 0x41, 0xe2, 0x34, 0x5f, 0x1f, 0x56, 0xdf,
138 0x24, 0x58, 0xf4, 0x26, 0xd1, 0x55, 0xb4, 0xba, 0x2d, 0xb6, 0xdc,
139 0xd8, 0xc8,
140};
141
David Benjamin808f8322017-08-18 14:06:02 -0400142// fip_sig_extra is fips_sig with trailing data.
David Benjamin95e18c52015-01-10 23:37:17 -0500143static const uint8_t fips_sig_extra[] = {
144 0x30, 0x2d, 0x02, 0x15, 0x00, 0x8b, 0xac, 0x1a, 0xb6, 0x64, 0x10,
145 0x43, 0x5c, 0xb7, 0x18, 0x1f, 0x95, 0xb1, 0x6a, 0xb9, 0x7c, 0x92,
146 0xb3, 0x41, 0xc0, 0x02, 0x14, 0x41, 0xe2, 0x34, 0x5f, 0x1f, 0x56,
147 0xdf, 0x24, 0x58, 0xf4, 0x26, 0xd1, 0x55, 0xb4, 0xba, 0x2d, 0xb6,
148 0xdc, 0xd8, 0xc8, 0x00,
149};
150
David Benjamin808f8322017-08-18 14:06:02 -0400151// fips_sig_lengths is fips_sig with a non-minimally encoded length.
David Benjamin95e18c52015-01-10 23:37:17 -0500152static const uint8_t fips_sig_bad_length[] = {
153 0x30, 0x81, 0x2d, 0x02, 0x15, 0x00, 0x8b, 0xac, 0x1a, 0xb6, 0x64,
154 0x10, 0x43, 0x5c, 0xb7, 0x18, 0x1f, 0x95, 0xb1, 0x6a, 0xb9, 0x7c,
155 0x92, 0xb3, 0x41, 0xc0, 0x02, 0x14, 0x41, 0xe2, 0x34, 0x5f, 0x1f,
156 0x56, 0xdf, 0x24, 0x58, 0xf4, 0x26, 0xd1, 0x55, 0xb4, 0xba, 0x2d,
157 0xb6, 0xdc, 0xd8, 0xc8, 0x00,
158};
159
David Benjamin808f8322017-08-18 14:06:02 -0400160// fips_sig_bad_r is fips_sig with a bad r value.
David Benjamin95e18c52015-01-10 23:37:17 -0500161static const uint8_t fips_sig_bad_r[] = {
162 0x30, 0x2d, 0x02, 0x15, 0x00, 0x8c, 0xac, 0x1a, 0xb6, 0x64, 0x10,
163 0x43, 0x5c, 0xb7, 0x18, 0x1f, 0x95, 0xb1, 0x6a, 0xb9, 0x7c, 0x92,
164 0xb3, 0x41, 0xc0, 0x02, 0x14, 0x41, 0xe2, 0x34, 0x5f, 0x1f, 0x56,
165 0xdf, 0x24, 0x58, 0xf4, 0x26, 0xd1, 0x55, 0xb4, 0xba, 0x2d, 0xb6,
166 0xdc, 0xd8, 0xc8,
167};
Adam Langley95c29f32014-06-20 12:00:00 -0700168
David Benjamind17d1da2016-12-21 22:16:43 -0500169static bssl::UniquePtr<DSA> GetFIPSDSA(void) {
170 bssl::UniquePtr<DSA> dsa(DSA_new());
David Benjamin95e18c52015-01-10 23:37:17 -0500171 if (!dsa) {
David Benjamind17d1da2016-12-21 22:16:43 -0500172 return nullptr;
David Benjamin95e18c52015-01-10 23:37:17 -0500173 }
David Benjamind17d1da2016-12-21 22:16:43 -0500174 dsa->p = BN_bin2bn(fips_p, sizeof(fips_p), nullptr);
175 dsa->q = BN_bin2bn(fips_q, sizeof(fips_q), nullptr);
176 dsa->g = BN_bin2bn(fips_g, sizeof(fips_g), nullptr);
177 dsa->pub_key = BN_bin2bn(fips_y, sizeof(fips_y), nullptr);
178 dsa->priv_key = BN_bin2bn(fips_x, sizeof(fips_x), nullptr);
179 if (dsa->p == nullptr || dsa->q == nullptr || dsa->g == nullptr ||
180 dsa->pub_key == nullptr || dsa->priv_key == nullptr) {
181 return nullptr;
David Benjamin95e18c52015-01-10 23:37:17 -0500182 }
183 return dsa;
184}
185
David Benjamind17d1da2016-12-21 22:16:43 -0500186struct GenerateContext {
187 FILE *out = nullptr;
188 int ok = 0;
189 int num = 0;
190};
191
192static int GenerateCallback(int p, int n, BN_GENCB *arg) {
193 GenerateContext *ctx = reinterpret_cast<GenerateContext *>(arg->arg);
194 char c = '*';
195 switch (p) {
196 case 0:
197 c = '.';
198 ctx->num++;
199 break;
200 case 1:
201 c = '+';
202 break;
203 case 2:
204 c = '*';
205 ctx->ok++;
206 break;
207 case 3:
208 c = '\n';
209 }
210 fputc(c, ctx->out);
211 fflush(ctx->out);
212 if (!ctx->ok && p == 0 && ctx->num > 1) {
213 fprintf(stderr, "error in dsatest\n");
214 return 0;
215 }
216 return 1;
217}
218
219static int TestGenerate(FILE *out) {
Adam Langley95c29f32014-06-20 12:00:00 -0700220 BN_GENCB cb;
David Benjamind17d1da2016-12-21 22:16:43 -0500221 int counter, i, j;
David Benjamin95e18c52015-01-10 23:37:17 -0500222 uint8_t buf[256];
Adam Langley95c29f32014-06-20 12:00:00 -0700223 unsigned long h;
David Benjamin95e18c52015-01-10 23:37:17 -0500224 uint8_t sig[256];
Adam Langley95c29f32014-06-20 12:00:00 -0700225 unsigned int siglen;
226
Brian Smith9da82c12015-03-12 11:36:41 +0800227 fprintf(out, "test generation of DSA parameters\n");
Adam Langley95c29f32014-06-20 12:00:00 -0700228
David Benjamind17d1da2016-12-21 22:16:43 -0500229 GenerateContext ctx;
230 ctx.out = out;
231 BN_GENCB_set(&cb, GenerateCallback, &ctx);
232 bssl::UniquePtr<DSA> dsa(DSA_new());
233 if (!dsa ||
234 !DSA_generate_parameters_ex(dsa.get(), 512, seed, 20, &counter, &h,
235 &cb)) {
236 return false;
Adam Langley95c29f32014-06-20 12:00:00 -0700237 }
238
Brian Smith9da82c12015-03-12 11:36:41 +0800239 fprintf(out, "seed\n");
Adam Langley95c29f32014-06-20 12:00:00 -0700240 for (i = 0; i < 20; i += 4) {
Brian Smith9da82c12015-03-12 11:36:41 +0800241 fprintf(out, "%02X%02X%02X%02X ", seed[i], seed[i + 1], seed[i + 2],
242 seed[i + 3]);
Adam Langley95c29f32014-06-20 12:00:00 -0700243 }
Brian Smith9da82c12015-03-12 11:36:41 +0800244 fprintf(out, "\ncounter=%d h=%ld\n", counter, h);
Adam Langley95c29f32014-06-20 12:00:00 -0700245
246 if (counter != 105) {
Brian Smith9da82c12015-03-12 11:36:41 +0800247 fprintf(stderr, "counter should be 105\n");
David Benjamind17d1da2016-12-21 22:16:43 -0500248 return false;
Adam Langley95c29f32014-06-20 12:00:00 -0700249 }
250 if (h != 2) {
Brian Smith9da82c12015-03-12 11:36:41 +0800251 fprintf(stderr, "h should be 2\n");
David Benjamind17d1da2016-12-21 22:16:43 -0500252 return false;
Adam Langley95c29f32014-06-20 12:00:00 -0700253 }
254
255 i = BN_bn2bin(dsa->q, buf);
David Benjamin95e18c52015-01-10 23:37:17 -0500256 j = sizeof(fips_q);
David Benjamin17cf2cb2016-12-13 01:07:13 -0500257 if (i != j || OPENSSL_memcmp(buf, fips_q, i) != 0) {
Brian Smith9da82c12015-03-12 11:36:41 +0800258 fprintf(stderr, "q value is wrong\n");
David Benjamind17d1da2016-12-21 22:16:43 -0500259 return false;
Adam Langley95c29f32014-06-20 12:00:00 -0700260 }
261
262 i = BN_bn2bin(dsa->p, buf);
David Benjamin95e18c52015-01-10 23:37:17 -0500263 j = sizeof(fips_p);
David Benjamin17cf2cb2016-12-13 01:07:13 -0500264 if (i != j || OPENSSL_memcmp(buf, fips_p, i) != 0) {
Brian Smith9da82c12015-03-12 11:36:41 +0800265 fprintf(stderr, "p value is wrong\n");
David Benjamind17d1da2016-12-21 22:16:43 -0500266 return false;
Adam Langley95c29f32014-06-20 12:00:00 -0700267 }
268
269 i = BN_bn2bin(dsa->g, buf);
David Benjamin95e18c52015-01-10 23:37:17 -0500270 j = sizeof(fips_g);
David Benjamin17cf2cb2016-12-13 01:07:13 -0500271 if (i != j || OPENSSL_memcmp(buf, fips_g, i) != 0) {
Brian Smith9da82c12015-03-12 11:36:41 +0800272 fprintf(stderr, "g value is wrong\n");
David Benjamind17d1da2016-12-21 22:16:43 -0500273 return false;
Adam Langley95c29f32014-06-20 12:00:00 -0700274 }
275
David Benjamind17d1da2016-12-21 22:16:43 -0500276 if (!DSA_generate_key(dsa.get()) ||
277 !DSA_sign(0, fips_digest, sizeof(fips_digest), sig, &siglen, dsa.get())) {
278 return false;
David Benjamin3fa65f02015-05-15 19:11:57 -0400279 }
David Benjamind17d1da2016-12-21 22:16:43 -0500280 if (DSA_verify(0, fips_digest, sizeof(fips_digest), sig, siglen, dsa.get()) !=
281 1) {
Brian Smith9da82c12015-03-12 11:36:41 +0800282 fprintf(stderr, "verification failure\n");
David Benjamind17d1da2016-12-21 22:16:43 -0500283 return false;
Adam Langley95c29f32014-06-20 12:00:00 -0700284 }
285
David Benjamind17d1da2016-12-21 22:16:43 -0500286 return true;
David Benjamin95e18c52015-01-10 23:37:17 -0500287}
Adam Langley95c29f32014-06-20 12:00:00 -0700288
David Benjamind17d1da2016-12-21 22:16:43 -0500289static bool TestVerify(const uint8_t *sig, size_t sig_len, int expect) {
290 bssl::UniquePtr<DSA> dsa = GetFIPSDSA();
291 if (!dsa) {
292 return false;
Adam Langley95c29f32014-06-20 12:00:00 -0700293 }
294
David Benjamind17d1da2016-12-21 22:16:43 -0500295 int ret =
296 DSA_verify(0, fips_digest, sizeof(fips_digest), sig, sig_len, dsa.get());
David Benjamin95e18c52015-01-10 23:37:17 -0500297 if (ret != expect) {
Brian Smith9da82c12015-03-12 11:36:41 +0800298 fprintf(stderr, "DSA_verify returned %d, want %d\n", ret, expect);
David Benjamind17d1da2016-12-21 22:16:43 -0500299 return false;
David Benjamin95e18c52015-01-10 23:37:17 -0500300 }
David Benjamind17d1da2016-12-21 22:16:43 -0500301
David Benjamin808f8322017-08-18 14:06:02 -0400302 // Clear any errors from a test with expected failure.
David Benjamin95e18c52015-01-10 23:37:17 -0500303 ERR_clear_error();
David Benjamind17d1da2016-12-21 22:16:43 -0500304 return true;
David Benjamin95e18c52015-01-10 23:37:17 -0500305}
306
David Benjamin96628432017-01-19 19:05:47 -0500307// TODO(davidben): Convert this file to GTest properly.
308TEST(DSATest, AllTests) {
David Benjamind17d1da2016-12-21 22:16:43 -0500309 if (!TestGenerate(stdout) ||
310 !TestVerify(fips_sig, sizeof(fips_sig), 1) ||
311 !TestVerify(fips_sig_negative, sizeof(fips_sig_negative), -1) ||
312 !TestVerify(fips_sig_extra, sizeof(fips_sig_extra), -1) ||
313 !TestVerify(fips_sig_bad_length, sizeof(fips_sig_bad_length), -1) ||
314 !TestVerify(fips_sig_bad_r, sizeof(fips_sig_bad_r), 0)) {
David Benjamin96628432017-01-19 19:05:47 -0500315 ADD_FAILURE() << "Tests failed";
David Benjamin95e18c52015-01-10 23:37:17 -0500316 }
Adam Langley95c29f32014-06-20 12:00:00 -0700317}