dsa_test.cc
Go to the documentation of this file.
1 /* 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 
62 #include <stdio.h>
63 #include <string.h>
64 
65 #include <vector>
66 
67 #include <gtest/gtest.h>
68 
69 #include <openssl/bn.h>
70 #include <openssl/crypto.h>
71 #include <openssl/err.h>
72 
73 #include "../internal.h"
74 
75 
76 // The following values are taken from the updated Appendix 5 to FIPS PUB 186
77 // and also appear in Appendix 5 to FIPS PUB 186-1.
78 
79 static const uint8_t seed[20] = {
80  0xd5, 0x01, 0x4e, 0x4b, 0x60, 0xef, 0x2b, 0xa8, 0xb6, 0x21, 0x1b,
81  0x40, 0x62, 0xba, 0x32, 0x24, 0xe0, 0x42, 0x7d, 0xd3,
82 };
83 
84 static const uint8_t fips_p[] = {
85  0x8d, 0xf2, 0xa4, 0x94, 0x49, 0x22, 0x76, 0xaa, 0x3d, 0x25, 0x75,
86  0x9b, 0xb0, 0x68, 0x69, 0xcb, 0xea, 0xc0, 0xd8, 0x3a, 0xfb, 0x8d,
87  0x0c, 0xf7, 0xcb, 0xb8, 0x32, 0x4f, 0x0d, 0x78, 0x82, 0xe5, 0xd0,
88  0x76, 0x2f, 0xc5, 0xb7, 0x21, 0x0e, 0xaf, 0xc2, 0xe9, 0xad, 0xac,
89  0x32, 0xab, 0x7a, 0xac, 0x49, 0x69, 0x3d, 0xfb, 0xf8, 0x37, 0x24,
90  0xc2, 0xec, 0x07, 0x36, 0xee, 0x31, 0xc8, 0x02, 0x91,
91 };
92 
93 static const uint8_t fips_q[] = {
94  0xc7, 0x73, 0x21, 0x8c, 0x73, 0x7e, 0xc8, 0xee, 0x99, 0x3b, 0x4f,
95  0x2d, 0xed, 0x30, 0xf4, 0x8e, 0xda, 0xce, 0x91, 0x5f,
96 };
97 
98 static const uint8_t fips_g[] = {
99  0x62, 0x6d, 0x02, 0x78, 0x39, 0xea, 0x0a, 0x13, 0x41, 0x31, 0x63,
100  0xa5, 0x5b, 0x4c, 0xb5, 0x00, 0x29, 0x9d, 0x55, 0x22, 0x95, 0x6c,
101  0xef, 0xcb, 0x3b, 0xff, 0x10, 0xf3, 0x99, 0xce, 0x2c, 0x2e, 0x71,
102  0xcb, 0x9d, 0xe5, 0xfa, 0x24, 0xba, 0xbf, 0x58, 0xe5, 0xb7, 0x95,
103  0x21, 0x92, 0x5c, 0x9c, 0xc4, 0x2e, 0x9f, 0x6f, 0x46, 0x4b, 0x08,
104  0x8c, 0xc5, 0x72, 0xaf, 0x53, 0xe6, 0xd7, 0x88, 0x02,
105 };
106 
107 static const uint8_t fips_x[] = {
108  0x20, 0x70, 0xb3, 0x22, 0x3d, 0xba, 0x37, 0x2f, 0xde, 0x1c, 0x0f,
109  0xfc, 0x7b, 0x2e, 0x3b, 0x49, 0x8b, 0x26, 0x06, 0x14,
110 };
111 
112 static const uint8_t fips_y[] = {
113  0x19, 0x13, 0x18, 0x71, 0xd7, 0x5b, 0x16, 0x12, 0xa8, 0x19, 0xf2,
114  0x9d, 0x78, 0xd1, 0xb0, 0xd7, 0x34, 0x6f, 0x7a, 0xa7, 0x7b, 0xb6,
115  0x2a, 0x85, 0x9b, 0xfd, 0x6c, 0x56, 0x75, 0xda, 0x9d, 0x21, 0x2d,
116  0x3a, 0x36, 0xef, 0x16, 0x72, 0xef, 0x66, 0x0b, 0x8c, 0x7c, 0x25,
117  0x5c, 0xc0, 0xec, 0x74, 0x85, 0x8f, 0xba, 0x33, 0xf4, 0x4c, 0x06,
118  0x69, 0x96, 0x30, 0xa7, 0x6b, 0x03, 0x0e, 0xe3, 0x33,
119 };
120 
121 static const uint8_t fips_digest[] = {
122  0xa9, 0x99, 0x3e, 0x36, 0x47, 0x06, 0x81, 0x6a, 0xba, 0x3e, 0x25,
123  0x71, 0x78, 0x50, 0xc2, 0x6c, 0x9c, 0xd0, 0xd8, 0x9d,
124 };
125 
126 // fips_sig is a DER-encoded version of the r and s values in FIPS PUB 186-1.
127 static const uint8_t fips_sig[] = {
128  0x30, 0x2d, 0x02, 0x15, 0x00, 0x8b, 0xac, 0x1a, 0xb6, 0x64, 0x10,
129  0x43, 0x5c, 0xb7, 0x18, 0x1f, 0x95, 0xb1, 0x6a, 0xb9, 0x7c, 0x92,
130  0xb3, 0x41, 0xc0, 0x02, 0x14, 0x41, 0xe2, 0x34, 0x5f, 0x1f, 0x56,
131  0xdf, 0x24, 0x58, 0xf4, 0x26, 0xd1, 0x55, 0xb4, 0xba, 0x2d, 0xb6,
132  0xdc, 0xd8, 0xc8,
133 };
134 
135 // fips_sig_negative is fips_sig with r encoded as a negative number.
136 static const uint8_t fips_sig_negative[] = {
137  0x30, 0x2c, 0x02, 0x14, 0x8b, 0xac, 0x1a, 0xb6, 0x64, 0x10, 0x43,
138  0x5c, 0xb7, 0x18, 0x1f, 0x95, 0xb1, 0x6a, 0xb9, 0x7c, 0x92, 0xb3,
139  0x41, 0xc0, 0x02, 0x14, 0x41, 0xe2, 0x34, 0x5f, 0x1f, 0x56, 0xdf,
140  0x24, 0x58, 0xf4, 0x26, 0xd1, 0x55, 0xb4, 0xba, 0x2d, 0xb6, 0xdc,
141  0xd8, 0xc8,
142 };
143 
144 // fip_sig_extra is fips_sig with trailing data.
145 static const uint8_t fips_sig_extra[] = {
146  0x30, 0x2d, 0x02, 0x15, 0x00, 0x8b, 0xac, 0x1a, 0xb6, 0x64, 0x10,
147  0x43, 0x5c, 0xb7, 0x18, 0x1f, 0x95, 0xb1, 0x6a, 0xb9, 0x7c, 0x92,
148  0xb3, 0x41, 0xc0, 0x02, 0x14, 0x41, 0xe2, 0x34, 0x5f, 0x1f, 0x56,
149  0xdf, 0x24, 0x58, 0xf4, 0x26, 0xd1, 0x55, 0xb4, 0xba, 0x2d, 0xb6,
150  0xdc, 0xd8, 0xc8, 0x00,
151 };
152 
153 // fips_sig_lengths is fips_sig with a non-minimally encoded length.
154 static const uint8_t fips_sig_bad_length[] = {
155  0x30, 0x81, 0x2d, 0x02, 0x15, 0x00, 0x8b, 0xac, 0x1a, 0xb6, 0x64,
156  0x10, 0x43, 0x5c, 0xb7, 0x18, 0x1f, 0x95, 0xb1, 0x6a, 0xb9, 0x7c,
157  0x92, 0xb3, 0x41, 0xc0, 0x02, 0x14, 0x41, 0xe2, 0x34, 0x5f, 0x1f,
158  0x56, 0xdf, 0x24, 0x58, 0xf4, 0x26, 0xd1, 0x55, 0xb4, 0xba, 0x2d,
159  0xb6, 0xdc, 0xd8, 0xc8, 0x00,
160 };
161 
162 // fips_sig_bad_r is fips_sig with a bad r value.
163 static const uint8_t fips_sig_bad_r[] = {
164  0x30, 0x2d, 0x02, 0x15, 0x00, 0x8c, 0xac, 0x1a, 0xb6, 0x64, 0x10,
165  0x43, 0x5c, 0xb7, 0x18, 0x1f, 0x95, 0xb1, 0x6a, 0xb9, 0x7c, 0x92,
166  0xb3, 0x41, 0xc0, 0x02, 0x14, 0x41, 0xe2, 0x34, 0x5f, 0x1f, 0x56,
167  0xdf, 0x24, 0x58, 0xf4, 0x26, 0xd1, 0x55, 0xb4, 0xba, 0x2d, 0xb6,
168  0xdc, 0xd8, 0xc8,
169 };
170 
171 static bssl::UniquePtr<DSA> GetFIPSDSA(void) {
172  bssl::UniquePtr<DSA> dsa(DSA_new());
173  if (!dsa) {
174  return nullptr;
175  }
176  dsa->p = BN_bin2bn(fips_p, sizeof(fips_p), nullptr);
177  dsa->q = BN_bin2bn(fips_q, sizeof(fips_q), nullptr);
178  dsa->g = BN_bin2bn(fips_g, sizeof(fips_g), nullptr);
179  dsa->pub_key = BN_bin2bn(fips_y, sizeof(fips_y), nullptr);
180  dsa->priv_key = BN_bin2bn(fips_x, sizeof(fips_x), nullptr);
181  if (dsa->p == nullptr || dsa->q == nullptr || dsa->g == nullptr ||
182  dsa->pub_key == nullptr || dsa->priv_key == nullptr) {
183  return nullptr;
184  }
185  return dsa;
186 }
187 
189  FILE *out = nullptr;
190  int ok = 0;
191  int num = 0;
192 };
193 
194 static int GenerateCallback(int p, int n, BN_GENCB *arg) {
195  GenerateContext *ctx = reinterpret_cast<GenerateContext *>(arg->arg);
196  char c = '*';
197  switch (p) {
198  case 0:
199  c = '.';
200  ctx->num++;
201  break;
202  case 1:
203  c = '+';
204  break;
205  case 2:
206  c = '*';
207  ctx->ok++;
208  break;
209  case 3:
210  c = '\n';
211  }
212  fputc(c, ctx->out);
213  fflush(ctx->out);
214  if (!ctx->ok && p == 0 && ctx->num > 1) {
215  fprintf(stderr, "error in dsatest\n");
216  return 0;
217  }
218  return 1;
219 }
220 
221 static int TestGenerate(FILE *out) {
222  BN_GENCB cb;
223  int counter, i, j;
224  uint8_t buf[256];
225  unsigned long h;
226  uint8_t sig[256];
227  unsigned int siglen;
228 
229  fprintf(out, "test generation of DSA parameters\n");
230 
232  ctx.out = out;
234  bssl::UniquePtr<DSA> dsa(DSA_new());
235  if (!dsa ||
236  !DSA_generate_parameters_ex(dsa.get(), 512, seed, 20, &counter, &h,
237  &cb)) {
238  return false;
239  }
240 
241  fprintf(out, "seed\n");
242  for (i = 0; i < 20; i += 4) {
243  fprintf(out, "%02X%02X%02X%02X ", seed[i], seed[i + 1], seed[i + 2],
244  seed[i + 3]);
245  }
246  fprintf(out, "\ncounter=%d h=%ld\n", counter, h);
247 
248  if (counter != 105) {
249  fprintf(stderr, "counter should be 105\n");
250  return false;
251  }
252  if (h != 2) {
253  fprintf(stderr, "h should be 2\n");
254  return false;
255  }
256 
257  i = BN_bn2bin(dsa->q, buf);
258  j = sizeof(fips_q);
259  if (i != j || OPENSSL_memcmp(buf, fips_q, i) != 0) {
260  fprintf(stderr, "q value is wrong\n");
261  return false;
262  }
263 
264  i = BN_bn2bin(dsa->p, buf);
265  j = sizeof(fips_p);
266  if (i != j || OPENSSL_memcmp(buf, fips_p, i) != 0) {
267  fprintf(stderr, "p value is wrong\n");
268  return false;
269  }
270 
271  i = BN_bn2bin(dsa->g, buf);
272  j = sizeof(fips_g);
273  if (i != j || OPENSSL_memcmp(buf, fips_g, i) != 0) {
274  fprintf(stderr, "g value is wrong\n");
275  return false;
276  }
277 
278  if (!DSA_generate_key(dsa.get()) ||
279  !DSA_sign(0, fips_digest, sizeof(fips_digest), sig, &siglen, dsa.get())) {
280  return false;
281  }
282  if (DSA_verify(0, fips_digest, sizeof(fips_digest), sig, siglen, dsa.get()) !=
283  1) {
284  fprintf(stderr, "verification failure\n");
285  return false;
286  }
287 
288  return true;
289 }
290 
291 static bool TestVerify(const uint8_t *sig, size_t sig_len, int expect) {
292  bssl::UniquePtr<DSA> dsa = GetFIPSDSA();
293  if (!dsa) {
294  return false;
295  }
296 
297  int ret =
298  DSA_verify(0, fips_digest, sizeof(fips_digest), sig, sig_len, dsa.get());
299  if (ret != expect) {
300  fprintf(stderr, "DSA_verify returned %d, want %d\n", ret, expect);
301  return false;
302  }
303 
304  // Clear any errors from a test with expected failure.
305  ERR_clear_error();
306  return true;
307 }
308 
309 // TODO(davidben): Convert this file to GTest properly.
310 TEST(DSATest, AllTests) {
311  if (!TestGenerate(stdout) ||
312  !TestVerify(fips_sig, sizeof(fips_sig), 1) ||
314  !TestVerify(fips_sig_extra, sizeof(fips_sig_extra), -1) ||
316  !TestVerify(fips_sig_bad_r, sizeof(fips_sig_bad_r), 0)) {
317  ADD_FAILURE() << "Tests failed";
318  }
319 }
320 
321 TEST(DSATest, InvalidGroup) {
322  bssl::UniquePtr<DSA> dsa = GetFIPSDSA();
323  ASSERT_TRUE(dsa);
324  BN_zero(dsa->g);
325 
326  std::vector<uint8_t> sig(DSA_size(dsa.get()));
327  unsigned sig_len;
328  static const uint8_t kDigest[32] = {0};
329  EXPECT_FALSE(
330  DSA_sign(0, kDigest, sizeof(kDigest), sig.data(), &sig_len, dsa.get()));
334 }
EXPECT_FALSE
#define EXPECT_FALSE(condition)
Definition: bloaty/third_party/googletest/googletest/include/gtest/gtest.h:1970
bn.h
gen_build_yaml.out
dictionary out
Definition: src/benchmark/gen_build_yaml.py:24
GenerateContext::ok
int ok
Definition: dsa_test.cc:190
OPENSSL_memcmp
static int OPENSSL_memcmp(const void *s1, const void *s2, size_t n)
Definition: third_party/boringssl-with-bazel/src/crypto/internal.h:811
ctx
Definition: benchmark-async.c:30
DSA_sign
#define DSA_sign
Definition: boringssl_prefix_symbols.h:1291
demumble_test.stdout
stdout
Definition: demumble_test.py:38
fips_digest
static const uint8_t fips_digest[]
Definition: dsa_test.cc:121
fips_sig
static const uint8_t fips_sig[]
Definition: dsa_test.cc:127
BN_bin2bn
#define BN_bin2bn
Definition: boringssl_prefix_symbols.h:900
string.h
seed
static const uint8_t seed[20]
Definition: dsa_test.cc:79
buf
voidpf void * buf
Definition: bloaty/third_party/zlib/contrib/minizip/ioapi.h:136
TestVerify
static bool TestVerify(const uint8_t *sig, size_t sig_len, int expect)
Definition: dsa_test.cc:291
GenerateContext::out
FILE * out
Definition: dsa_test.cc:189
error_ref_leak.err
err
Definition: error_ref_leak.py:35
ctx
static struct test_ctx ctx
Definition: test-ipc-send-recv.c:65
xds_manager.p
p
Definition: xds_manager.py:60
uint8_t
unsigned char uint8_t
Definition: stdint-msvc2008.h:78
DSA_new
#define DSA_new
Definition: boringssl_prefix_symbols.h:1284
ERR_LIB_DSA
@ ERR_LIB_DSA
Definition: err.h:301
ERR_get_error
#define ERR_get_error
Definition: boringssl_prefix_symbols.h:1419
GenerateContext
Definition: dsa_test.cc:188
python_utils.port_server.stderr
stderr
Definition: port_server.py:51
EXPECT_EQ
#define EXPECT_EQ(a, b)
Definition: iomgr/time_averaged_stats_test.cc:27
uint32_t
unsigned int uint32_t
Definition: stdint-msvc2008.h:80
GenerateContext::num
int num
Definition: dsa_test.cc:191
TestGenerate
static int TestGenerate(FILE *out)
Definition: dsa_test.cc:221
c
void c(T a)
Definition: miscompile_with_no_unique_address_test.cc:40
DSA_generate_key
#define DSA_generate_key
Definition: boringssl_prefix_symbols.h:1270
ERR_GET_REASON
#define ERR_GET_REASON(packed_error)
Definition: err.h:171
GenerateCallback
static int GenerateCallback(int p, int n, BN_GENCB *arg)
Definition: dsa_test.cc:194
ERR_GET_LIB
#define ERR_GET_LIB(packed_error)
Definition: err.h:166
err.h
fips_y
static const uint8_t fips_y[]
Definition: dsa_test.cc:112
counter
static int counter
Definition: abseil-cpp/absl/flags/reflection_test.cc:131
crypto.h
DSA_generate_parameters_ex
#define DSA_generate_parameters_ex
Definition: boringssl_prefix_symbols.h:1271
fips_g
static const uint8_t fips_g[]
Definition: dsa_test.cc:98
arg
Definition: cmdline.cc:40
dsa.h
BN_bn2bin
#define BN_bn2bin
Definition: boringssl_prefix_symbols.h:901
DSA_size
#define DSA_size
Definition: boringssl_prefix_symbols.h:1292
ADD_FAILURE
#define ADD_FAILURE()
Definition: bloaty/third_party/googletest/googletest/include/gtest/gtest.h:1911
n
int n
Definition: abseil-cpp/absl/container/btree_test.cc:1080
bn_gencb_st
Definition: bn.h:656
BN_zero
#define BN_zero
Definition: boringssl_prefix_symbols.h:1004
fips_sig_bad_length
static const uint8_t fips_sig_bad_length[]
Definition: dsa_test.cc:154
benchmark.FILE
FILE
Definition: benchmark.py:21
DSA_R_INVALID_PARAMETERS
#define DSA_R_INVALID_PARAMETERS
Definition: dsa.h:441
fips_sig_extra
static const uint8_t fips_sig_extra[]
Definition: dsa_test.cc:145
TEST
TEST(DSATest, AllTests)
Definition: dsa_test.cc:310
fips_sig_negative
static const uint8_t fips_sig_negative[]
Definition: dsa_test.cc:136
ret
UniquePtr< SSL_SESSION > ret
Definition: ssl_x509.cc:1029
DSA_verify
#define DSA_verify
Definition: boringssl_prefix_symbols.h:1294
ASSERT_TRUE
#define ASSERT_TRUE(condition)
Definition: bloaty/third_party/googletest/googletest/include/gtest/gtest.h:1973
ERR_clear_error
#define ERR_clear_error
Definition: boringssl_prefix_symbols.h:1413
BN_GENCB_set
#define BN_GENCB_set
Definition: boringssl_prefix_symbols.h:888
GetFIPSDSA
static bssl::UniquePtr< DSA > GetFIPSDSA(void)
Definition: dsa_test.cc:171
fips_p
static const uint8_t fips_p[]
Definition: dsa_test.cc:84
fips_q
static const uint8_t fips_q[]
Definition: dsa_test.cc:93
fips_x
static const uint8_t fips_x[]
Definition: dsa_test.cc:107
cb
OPENSSL_EXPORT pem_password_cb * cb
Definition: pem.h:351
i
uint64_t i
Definition: abseil-cpp/absl/container/btree_benchmark.cc:230
fips_sig_bad_r
static const uint8_t fips_sig_bad_r[]
Definition: dsa_test.cc:163


grpc
Author(s):
autogenerated on Thu Mar 13 2025 02:59:13