1 // Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 #include <openssl/dsa.h>
16
17 #include <stdio.h>
18 #include <string.h>
19
20 #include <vector>
21
22 #include <gtest/gtest.h>
23
24 #include <openssl/bn.h>
25 #include <openssl/crypto.h>
26 #include <openssl/err.h>
27 #include <openssl/pem.h>
28 #include <openssl/span.h>
29
30 #include "../test/test_util.h"
31
32
33 // The following values are taken from the updated Appendix 5 to FIPS PUB 186
34 // and also appear in Appendix 5 to FIPS PUB 186-1.
35
36 static const uint8_t seed[20] = {
37 0xd5, 0x01, 0x4e, 0x4b, 0x60, 0xef, 0x2b, 0xa8, 0xb6, 0x21, 0x1b,
38 0x40, 0x62, 0xba, 0x32, 0x24, 0xe0, 0x42, 0x7d, 0xd3,
39 };
40
41 static const uint8_t fips_p[] = {
42 0x8d, 0xf2, 0xa4, 0x94, 0x49, 0x22, 0x76, 0xaa, 0x3d, 0x25, 0x75,
43 0x9b, 0xb0, 0x68, 0x69, 0xcb, 0xea, 0xc0, 0xd8, 0x3a, 0xfb, 0x8d,
44 0x0c, 0xf7, 0xcb, 0xb8, 0x32, 0x4f, 0x0d, 0x78, 0x82, 0xe5, 0xd0,
45 0x76, 0x2f, 0xc5, 0xb7, 0x21, 0x0e, 0xaf, 0xc2, 0xe9, 0xad, 0xac,
46 0x32, 0xab, 0x7a, 0xac, 0x49, 0x69, 0x3d, 0xfb, 0xf8, 0x37, 0x24,
47 0xc2, 0xec, 0x07, 0x36, 0xee, 0x31, 0xc8, 0x02, 0x91,
48 };
49
50 static const uint8_t fips_q[] = {
51 0xc7, 0x73, 0x21, 0x8c, 0x73, 0x7e, 0xc8, 0xee, 0x99, 0x3b, 0x4f,
52 0x2d, 0xed, 0x30, 0xf4, 0x8e, 0xda, 0xce, 0x91, 0x5f,
53 };
54
55 static const uint8_t fips_g[] = {
56 0x62, 0x6d, 0x02, 0x78, 0x39, 0xea, 0x0a, 0x13, 0x41, 0x31, 0x63,
57 0xa5, 0x5b, 0x4c, 0xb5, 0x00, 0x29, 0x9d, 0x55, 0x22, 0x95, 0x6c,
58 0xef, 0xcb, 0x3b, 0xff, 0x10, 0xf3, 0x99, 0xce, 0x2c, 0x2e, 0x71,
59 0xcb, 0x9d, 0xe5, 0xfa, 0x24, 0xba, 0xbf, 0x58, 0xe5, 0xb7, 0x95,
60 0x21, 0x92, 0x5c, 0x9c, 0xc4, 0x2e, 0x9f, 0x6f, 0x46, 0x4b, 0x08,
61 0x8c, 0xc5, 0x72, 0xaf, 0x53, 0xe6, 0xd7, 0x88, 0x02,
62 };
63
64 static const uint8_t fips_x[] = {
65 0x20, 0x70, 0xb3, 0x22, 0x3d, 0xba, 0x37, 0x2f, 0xde, 0x1c, 0x0f,
66 0xfc, 0x7b, 0x2e, 0x3b, 0x49, 0x8b, 0x26, 0x06, 0x14,
67 };
68
69 static const uint8_t fips_y[] = {
70 0x19, 0x13, 0x18, 0x71, 0xd7, 0x5b, 0x16, 0x12, 0xa8, 0x19, 0xf2,
71 0x9d, 0x78, 0xd1, 0xb0, 0xd7, 0x34, 0x6f, 0x7a, 0xa7, 0x7b, 0xb6,
72 0x2a, 0x85, 0x9b, 0xfd, 0x6c, 0x56, 0x75, 0xda, 0x9d, 0x21, 0x2d,
73 0x3a, 0x36, 0xef, 0x16, 0x72, 0xef, 0x66, 0x0b, 0x8c, 0x7c, 0x25,
74 0x5c, 0xc0, 0xec, 0x74, 0x85, 0x8f, 0xba, 0x33, 0xf4, 0x4c, 0x06,
75 0x69, 0x96, 0x30, 0xa7, 0x6b, 0x03, 0x0e, 0xe3, 0x33,
76 };
77
78 static const uint8_t fips_digest[] = {
79 0xa9, 0x99, 0x3e, 0x36, 0x47, 0x06, 0x81, 0x6a, 0xba, 0x3e, 0x25,
80 0x71, 0x78, 0x50, 0xc2, 0x6c, 0x9c, 0xd0, 0xd8, 0x9d,
81 };
82
83 // fips_sig is a DER-encoded version of the r and s values in FIPS PUB 186-1.
84 static const uint8_t fips_sig[] = {
85 0x30, 0x2d, 0x02, 0x15, 0x00, 0x8b, 0xac, 0x1a, 0xb6, 0x64, 0x10,
86 0x43, 0x5c, 0xb7, 0x18, 0x1f, 0x95, 0xb1, 0x6a, 0xb9, 0x7c, 0x92,
87 0xb3, 0x41, 0xc0, 0x02, 0x14, 0x41, 0xe2, 0x34, 0x5f, 0x1f, 0x56,
88 0xdf, 0x24, 0x58, 0xf4, 0x26, 0xd1, 0x55, 0xb4, 0xba, 0x2d, 0xb6,
89 0xdc, 0xd8, 0xc8,
90 };
91
92 // fips_sig_negative is fips_sig with r encoded as a negative number.
93 static const uint8_t fips_sig_negative[] = {
94 0x30, 0x2c, 0x02, 0x14, 0x8b, 0xac, 0x1a, 0xb6, 0x64, 0x10, 0x43,
95 0x5c, 0xb7, 0x18, 0x1f, 0x95, 0xb1, 0x6a, 0xb9, 0x7c, 0x92, 0xb3,
96 0x41, 0xc0, 0x02, 0x14, 0x41, 0xe2, 0x34, 0x5f, 0x1f, 0x56, 0xdf,
97 0x24, 0x58, 0xf4, 0x26, 0xd1, 0x55, 0xb4, 0xba, 0x2d, 0xb6, 0xdc,
98 0xd8, 0xc8,
99 };
100
101 // fip_sig_extra is fips_sig with trailing data.
102 static const uint8_t fips_sig_extra[] = {
103 0x30, 0x2d, 0x02, 0x15, 0x00, 0x8b, 0xac, 0x1a, 0xb6, 0x64, 0x10,
104 0x43, 0x5c, 0xb7, 0x18, 0x1f, 0x95, 0xb1, 0x6a, 0xb9, 0x7c, 0x92,
105 0xb3, 0x41, 0xc0, 0x02, 0x14, 0x41, 0xe2, 0x34, 0x5f, 0x1f, 0x56,
106 0xdf, 0x24, 0x58, 0xf4, 0x26, 0xd1, 0x55, 0xb4, 0xba, 0x2d, 0xb6,
107 0xdc, 0xd8, 0xc8, 0x00,
108 };
109
110 // fips_sig_lengths is fips_sig with a non-minimally encoded length.
111 static const uint8_t fips_sig_bad_length[] = {
112 0x30, 0x81, 0x2d, 0x02, 0x15, 0x00, 0x8b, 0xac, 0x1a, 0xb6, 0x64,
113 0x10, 0x43, 0x5c, 0xb7, 0x18, 0x1f, 0x95, 0xb1, 0x6a, 0xb9, 0x7c,
114 0x92, 0xb3, 0x41, 0xc0, 0x02, 0x14, 0x41, 0xe2, 0x34, 0x5f, 0x1f,
115 0x56, 0xdf, 0x24, 0x58, 0xf4, 0x26, 0xd1, 0x55, 0xb4, 0xba, 0x2d,
116 0xb6, 0xdc, 0xd8, 0xc8, 0x00,
117 };
118
119 // fips_sig_bad_r is fips_sig with a bad r value.
120 static const uint8_t fips_sig_bad_r[] = {
121 0x30, 0x2d, 0x02, 0x15, 0x00, 0x8c, 0xac, 0x1a, 0xb6, 0x64, 0x10,
122 0x43, 0x5c, 0xb7, 0x18, 0x1f, 0x95, 0xb1, 0x6a, 0xb9, 0x7c, 0x92,
123 0xb3, 0x41, 0xc0, 0x02, 0x14, 0x41, 0xe2, 0x34, 0x5f, 0x1f, 0x56,
124 0xdf, 0x24, 0x58, 0xf4, 0x26, 0xd1, 0x55, 0xb4, 0xba, 0x2d, 0xb6,
125 0xdc, 0xd8, 0xc8,
126 };
127
GetFIPSDSAGroup(void)128 static bssl::UniquePtr<DSA> GetFIPSDSAGroup(void) {
129 bssl::UniquePtr<DSA> dsa(DSA_new());
130 if (!dsa) {
131 return nullptr;
132 }
133 bssl::UniquePtr<BIGNUM> p(BN_bin2bn(fips_p, sizeof(fips_p), nullptr));
134 bssl::UniquePtr<BIGNUM> q(BN_bin2bn(fips_q, sizeof(fips_q), nullptr));
135 bssl::UniquePtr<BIGNUM> g(BN_bin2bn(fips_g, sizeof(fips_g), nullptr));
136 if (!p || !q || !g || !DSA_set0_pqg(dsa.get(), p.get(), q.get(), g.get())) {
137 return nullptr;
138 }
139 // |DSA_set0_pqg| takes ownership.
140 p.release();
141 q.release();
142 g.release();
143 return dsa;
144 }
145
GetFIPSDSA(void)146 static bssl::UniquePtr<DSA> GetFIPSDSA(void) {
147 bssl::UniquePtr<DSA> dsa = GetFIPSDSAGroup();
148 if (!dsa) {
149 return nullptr;
150 }
151 bssl::UniquePtr<BIGNUM> pub_key(BN_bin2bn(fips_y, sizeof(fips_y), nullptr));
152 bssl::UniquePtr<BIGNUM> priv_key(BN_bin2bn(fips_x, sizeof(fips_x), nullptr));
153 if (!pub_key || !priv_key ||
154 !DSA_set0_key(dsa.get(), pub_key.get(), priv_key.get())) {
155 return nullptr;
156 }
157 // |DSA_set0_key| takes ownership.
158 pub_key.release();
159 priv_key.release();
160 return dsa;
161 }
162
TEST(DSATest,Generate)163 TEST(DSATest, Generate) {
164 bssl::UniquePtr<DSA> dsa(DSA_new());
165 ASSERT_TRUE(dsa);
166 int counter;
167 unsigned long h;
168 ASSERT_TRUE(DSA_generate_parameters_ex(dsa.get(), 512, seed, 20, &counter, &h,
169 nullptr));
170 EXPECT_EQ(counter, 105);
171 EXPECT_EQ(h, 2u);
172
173 auto expect_bn_bytes = [](const char *msg, const BIGNUM *bn,
174 bssl::Span<const uint8_t> bytes) {
175 std::vector<uint8_t> buf(BN_num_bytes(bn));
176 BN_bn2bin(bn, buf.data());
177 EXPECT_EQ(Bytes(buf), Bytes(bytes)) << msg;
178 };
179 expect_bn_bytes("q value is wrong", DSA_get0_q(dsa.get()), fips_q);
180 expect_bn_bytes("p value is wrong", DSA_get0_p(dsa.get()), fips_p);
181 expect_bn_bytes("g value is wrong", DSA_get0_g(dsa.get()), fips_g);
182
183 ASSERT_TRUE(DSA_generate_key(dsa.get()));
184
185 std::vector<uint8_t> sig(DSA_size(dsa.get()));
186 unsigned sig_len;
187 ASSERT_TRUE(DSA_sign(0, fips_digest, sizeof(fips_digest), sig.data(),
188 &sig_len, dsa.get()));
189
190 EXPECT_EQ(1, DSA_verify(0, fips_digest, sizeof(fips_digest), sig.data(),
191 sig_len, dsa.get()));
192 }
193
TEST(DSATest,GenerateParamsTooLarge)194 TEST(DSATest, GenerateParamsTooLarge) {
195 bssl::UniquePtr<DSA> dsa(DSA_new());
196 ASSERT_TRUE(dsa);
197 EXPECT_FALSE(DSA_generate_parameters_ex(
198 dsa.get(), 10001, /*seed=*/nullptr, /*seed_len=*/0,
199 /*out_counter=*/nullptr, /*out_h=*/nullptr,
200 /*cb=*/nullptr));
201 }
202
TEST(DSATest,GenerateKeyTooLarge)203 TEST(DSATest, GenerateKeyTooLarge) {
204 bssl::UniquePtr<DSA> dsa = GetFIPSDSA();
205 ASSERT_TRUE(dsa);
206 bssl::UniquePtr<BIGNUM> large_p(BN_new());
207 ASSERT_TRUE(large_p);
208 ASSERT_TRUE(BN_set_bit(large_p.get(), 10001));
209 ASSERT_TRUE(BN_set_bit(large_p.get(), 0));
210 ASSERT_TRUE(DSA_set0_pqg(dsa.get(), /*p=*/large_p.get(), /*q=*/nullptr,
211 /*g=*/nullptr));
212 large_p.release(); // |DSA_set0_pqg| takes ownership on success.
213
214 // Don't generate DSA keys if the group is too large.
215 EXPECT_FALSE(DSA_generate_key(dsa.get()));
216 }
217
TEST(DSATest,Verify)218 TEST(DSATest, Verify) {
219 bssl::UniquePtr<DSA> dsa = GetFIPSDSA();
220 ASSERT_TRUE(dsa);
221
222 EXPECT_EQ(1, DSA_verify(0, fips_digest, sizeof(fips_digest), fips_sig,
223 sizeof(fips_sig), dsa.get()));
224 EXPECT_EQ(-1,
225 DSA_verify(0, fips_digest, sizeof(fips_digest), fips_sig_negative,
226 sizeof(fips_sig_negative), dsa.get()));
227 EXPECT_EQ(-1, DSA_verify(0, fips_digest, sizeof(fips_digest), fips_sig_extra,
228 sizeof(fips_sig_extra), dsa.get()));
229 EXPECT_EQ(-1,
230 DSA_verify(0, fips_digest, sizeof(fips_digest), fips_sig_bad_length,
231 sizeof(fips_sig_bad_length), dsa.get()));
232 EXPECT_EQ(0, DSA_verify(0, fips_digest, sizeof(fips_digest), fips_sig_bad_r,
233 sizeof(fips_sig_bad_r), dsa.get()));
234 }
235
TEST(DSATest,InvalidGroup)236 TEST(DSATest, InvalidGroup) {
237 bssl::UniquePtr<DSA> dsa = GetFIPSDSA();
238 ASSERT_TRUE(dsa);
239 bssl::UniquePtr<BIGNUM> zero(BN_new());
240 ASSERT_TRUE(zero);
241 ASSERT_TRUE(DSA_set0_pqg(dsa.get(), /*p=*/nullptr, /*q=*/nullptr,
242 /*g=*/zero.release()));
243
244 std::vector<uint8_t> sig(DSA_size(dsa.get()));
245 unsigned sig_len;
246 static const uint8_t kDigest[32] = {0};
247 EXPECT_FALSE(
248 DSA_sign(0, kDigest, sizeof(kDigest), sig.data(), &sig_len, dsa.get()));
249 EXPECT_TRUE(
250 ErrorEquals(ERR_get_error(), ERR_LIB_DSA, DSA_R_INVALID_PARAMETERS));
251 }
252
253 // Signing and verifying should cleanly fail when the DSA object is empty.
TEST(DSATest,MissingParameters)254 TEST(DSATest, MissingParameters) {
255 bssl::UniquePtr<DSA> dsa(DSA_new());
256 ASSERT_TRUE(dsa);
257 EXPECT_EQ(-1, DSA_verify(0, fips_digest, sizeof(fips_digest), fips_sig,
258 sizeof(fips_sig), dsa.get()));
259
260 std::vector<uint8_t> sig(DSA_size(dsa.get()));
261 unsigned sig_len;
262 EXPECT_FALSE(DSA_sign(0, fips_digest, sizeof(fips_digest), sig.data(),
263 &sig_len, dsa.get()));
264 }
265
266 // Verifying should cleanly fail when the public key is missing.
TEST(DSATest,MissingPublic)267 TEST(DSATest, MissingPublic) {
268 bssl::UniquePtr<DSA> dsa = GetFIPSDSAGroup();
269 ASSERT_TRUE(dsa);
270 EXPECT_EQ(-1, DSA_verify(0, fips_digest, sizeof(fips_digest), fips_sig,
271 sizeof(fips_sig), dsa.get()));
272 }
273
274 // Signing should cleanly fail when the private key is missing.
TEST(DSATest,MissingPrivate)275 TEST(DSATest, MissingPrivate) {
276 bssl::UniquePtr<DSA> dsa = GetFIPSDSAGroup();
277 ASSERT_TRUE(dsa);
278
279 std::vector<uint8_t> sig(DSA_size(dsa.get()));
280 unsigned sig_len;
281 EXPECT_FALSE(DSA_sign(0, fips_digest, sizeof(fips_digest), sig.data(),
282 &sig_len, dsa.get()));
283 }
284
285 // A zero private key is invalid and can cause signing to loop forever.
TEST(DSATest,ZeroPrivateKey)286 TEST(DSATest, ZeroPrivateKey) {
287 bssl::UniquePtr<DSA> dsa = GetFIPSDSA();
288 ASSERT_TRUE(dsa);
289 bssl::UniquePtr<BIGNUM> zero(BN_new());
290 ASSERT_TRUE(zero);
291 ASSERT_TRUE(DSA_set0_key(dsa.get(), /*pub_key=*/nullptr,
292 /*priv_key=*/zero.release()));
293
294 static const uint8_t kZeroDigest[32] = {0};
295 std::vector<uint8_t> sig(DSA_size(dsa.get()));
296 unsigned sig_len;
297 EXPECT_FALSE(DSA_sign(0, kZeroDigest, sizeof(kZeroDigest), sig.data(),
298 &sig_len, dsa.get()));
299 }
300
301 // If the "field" is actually a ring and the "generator" of the multiplicative
302 // subgroup is actually nilpotent with low degree, DSA signing never completes.
303 // Test that we give up in the infinite loop.
TEST(DSATest,NilpotentGenerator)304 TEST(DSATest, NilpotentGenerator) {
305 static const char kPEM[] = R"(
306 -----BEGIN DSA PRIVATE KEY-----
307 MGECAQACFQHH+MnFXh4NNlZiV/zUVb5a5ib3kwIVAOP8ZOKvDwabKzEr/moq3y1z
308 E3vJAhUAl/2Ylx9fWbzHdh1URsc/c6IM/TECAQECFCsjU4AZRcuks45g1NMOUeCB
309 Epvg
310 -----END DSA PRIVATE KEY-----
311 )";
312 bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(kPEM, sizeof(kPEM)));
313 ASSERT_TRUE(bio);
314 bssl::UniquePtr<DSA> dsa(
315 PEM_read_bio_DSAPrivateKey(bio.get(), nullptr, nullptr, nullptr));
316 ASSERT_TRUE(dsa);
317
318 std::vector<uint8_t> sig(DSA_size(dsa.get()));
319 unsigned sig_len;
320 EXPECT_FALSE(DSA_sign(0, fips_digest, sizeof(fips_digest), sig.data(),
321 &sig_len, dsa.get()));
322 }
323
TEST(DSATest,Overwrite)324 TEST(DSATest, Overwrite) {
325 // Load an arbitrary DSA private key and use it.
326 static const char kPEM[] = R"(
327 -----BEGIN DSA PRIVATE KEY-----
328 MIIDTgIBAAKCAQEAyH68EuravtF+7PTFBtWJkwjmp0YJmh8e2Cdpu8ci3dZf87rk
329 GwXzfqYkAEkW5H4Hp0cxdICKFiqfxjSaiEauOrNV+nXWZS634hZ9H47I8HnAVS0p
330 5MmSmPJ7NNUowymMpyB6M6hfqHl/1pZd7avbTmnzb2SZ0kw0WLWJo6vMekepYWv9
331 3o1Xove4ci00hnkr7Qo9Bh/+z84jgeT2/MTdsCVtbuMv/mbcYLhCKVWPBozDZr/D
332 qwhGTlomsTRvP3WIbem3b5eYhQaPuMsKiAzntcinoxQXWrIoZB+xJyF/sI013uBI
333 i9ePSxY3704U4QGxVM0aR/6fzORz5kh8ZjhhywIdAI9YBUR6eoGevUaLq++qXiYW
334 TgXBXlyqE32ESbkCggEBAL/c5GerO5g25D0QsfgVIJtlZHQOwYauuWoUudaQiyf6
335 VhWLBNNTAGldkFGdtxsA42uqqZSXCki25LvN6PscGGvFy8oPWaa9TGt+l9Z5ZZiV
336 ShNpg71V9YuImsPB3BrQ4L6nZLfhBt6InzJ6KqjDNdg7u6lgnFKue7l6khzqNxbM
337 RgxHWMq7PkhMcl+RzpqbiGcxSHqraxldutqCWsnZzhKh4d4GdunuRY8GiFo0Axkb
338 Kn0Il3zm81ewv08F/ocu+IZQEzxTyR8YRQ99MLVbnwhVxndEdLjjetCX82l+/uEY
339 5fdUy0thR8odcDsvUc/tT57I+yhnno80HbpUUNw2+/sCggEAdh1wp/9CifYIp6T8
340 P/rIus6KberZ2Pv/n0bl+Gv8AoToA0zhZXIfY2l0TtanKmdLqPIvjqkN0v6zGSs+
341 +ahR1QzMQnK718mcsQmB4X6iP5LKgJ/t0g8LrDOxc/cNycmHq76MmF9RN5NEBz4+
342 PAnRIftm/b0UQflP6uy3gRQP2X7P8ZebCytOPKTZC4oLyCtvPevSkCiiauq/RGjL
343 k6xqRgLxMtmuyhT+dcVbtllV1p1xd9Bppnk17/kR5VCefo/e/7DHu163izRDW8tx
344 SrEmiVyVkRijY3bVZii7LPfMz5eEAWEDJRuFwyNv3i6j7CKeZw2d/hzu370Ua28F
345 s2lmkAIcLIFUDFrbC2nViaB5ATM9ARKk6F2QwnCfGCyZ6A==
346 -----END DSA PRIVATE KEY-----
347 )";
348 bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(kPEM, sizeof(kPEM)));
349 ASSERT_TRUE(bio);
350 bssl::UniquePtr<DSA> dsa(
351 PEM_read_bio_DSAPrivateKey(bio.get(), nullptr, nullptr, nullptr));
352 ASSERT_TRUE(dsa);
353
354 std::vector<uint8_t> sig(DSA_size(dsa.get()));
355 unsigned sig_len;
356 ASSERT_TRUE(DSA_sign(0, fips_digest, sizeof(fips_digest), sig.data(),
357 &sig_len, dsa.get()));
358 sig.resize(sig_len);
359 EXPECT_EQ(1, DSA_verify(0, fips_digest, sizeof(fips_digest), sig.data(),
360 sig.size(), dsa.get()));
361
362 // Overwrite it with the sample key.
363 bssl::UniquePtr<BIGNUM> p(BN_bin2bn(fips_p, sizeof(fips_p), nullptr));
364 ASSERT_TRUE(p);
365 bssl::UniquePtr<BIGNUM> q(BN_bin2bn(fips_q, sizeof(fips_q), nullptr));
366 ASSERT_TRUE(q);
367 bssl::UniquePtr<BIGNUM> g(BN_bin2bn(fips_g, sizeof(fips_g), nullptr));
368 ASSERT_TRUE(g);
369 ASSERT_TRUE(DSA_set0_pqg(dsa.get(), p.get(), q.get(), g.get()));
370 // |DSA_set0_pqg| takes ownership on success.
371 p.release();
372 q.release();
373 g.release();
374 bssl::UniquePtr<BIGNUM> pub_key(BN_bin2bn(fips_y, sizeof(fips_y), nullptr));
375 ASSERT_TRUE(pub_key);
376 bssl::UniquePtr<BIGNUM> priv_key(BN_bin2bn(fips_x, sizeof(fips_x), nullptr));
377 ASSERT_TRUE(priv_key);
378 ASSERT_TRUE(DSA_set0_key(dsa.get(), pub_key.get(), priv_key.get()));
379 // |DSA_set0_key| takes ownership on success.
380 pub_key.release();
381 priv_key.release();
382
383 // The key should now work correctly for the new parameters.
384 EXPECT_EQ(1, DSA_verify(0, fips_digest, sizeof(fips_digest), fips_sig,
385 sizeof(fips_sig), dsa.get()));
386
387 // Test signing by verifying it round-trips through the real key.
388 sig.resize(DSA_size(dsa.get()));
389 ASSERT_TRUE(DSA_sign(0, fips_digest, sizeof(fips_digest), sig.data(),
390 &sig_len, dsa.get()));
391 sig.resize(sig_len);
392 dsa = GetFIPSDSA();
393 ASSERT_TRUE(dsa);
394 EXPECT_EQ(1, DSA_verify(0, fips_digest, sizeof(fips_digest), sig.data(),
395 sig.size(), dsa.get()));
396 }
397