File bsc1185319-FIPS-KAT-for-ECDSA.patch of Package openssl-1_1
408
1
diff --git a/crypto/fips/fips_ecdsa_selftest.c b/crypto/fips/fips_ecdsa_selftest.c
2
index 9895aa8..77a1c77 100644
3
--- a/crypto/fips/fips_ecdsa_selftest.c
4
+++ b/crypto/fips/fips_ecdsa_selftest.c
5
6
* are met:
7
*
8
* 1. Redistributions of source code must retain the above copyright
9
- * notice, this list of conditions and the following disclaimer.
10
+ * notice, this list of conditions and the following disclaimer.
11
*
12
* 2. Redistributions in binary form must reproduce the above copyright
13
* notice, this list of conditions and the following disclaimer in
14
15
#include <openssl/bn.h>
16
17
#ifdef OPENSSL_FIPS
18
+#include <openssl/rand.h>
19
+#include "internal/nelem.h"
20
+#include "fips_locl.h"
21
22
-static const char P_256_name[] = "ECDSA P-256";
23
+/* functions to change the RAND_METHOD */
24
+static int fbytes(unsigned char *buf, int num);
25
26
-static const unsigned char P_256_d[] = {
27
- 0x51, 0xbd, 0x06, 0xa1, 0x1c, 0xda, 0xe2, 0x12, 0x99, 0xc9, 0x52, 0x3f,
28
- 0xea, 0xa4, 0xd2, 0xd1, 0xf4, 0x7f, 0xd4, 0x3e, 0xbd, 0xf8, 0xfc, 0x87,
29
- 0xdc, 0x82, 0x53, 0x21, 0xee, 0xa0, 0xdc, 0x64
30
-};
31
+static RAND_METHOD fake_rand;
32
+static const RAND_METHOD *old_rand;
33
+static int use_fake = 0;
34
+static const unsigned char *numbers[2];
35
+static int numbers_len[2];
36
37
-static const unsigned char P_256_qx[] = {
38
- 0x23, 0x89, 0xe0, 0xf4, 0x69, 0xe0, 0x49, 0xe5, 0xc7, 0xe5, 0x40, 0x6e,
39
- 0x8f, 0x25, 0xdd, 0xad, 0x11, 0x16, 0x14, 0x9b, 0xab, 0x44, 0x06, 0x31,
40
- 0xbf, 0x5e, 0xa6, 0x44, 0xac, 0x86, 0x00, 0x07
41
-};
42
+static int change_rand(void)
43
+{
44
+ /* save old rand method */
45
+ old_rand = RAND_get_rand_method();
46
+ if (!old_rand)
47
+ return 0;
48
+
49
+ fake_rand = *old_rand;
50
+ /* use own random function */
51
+ fake_rand.bytes = fbytes;
52
+ /* set new RAND_METHOD */
53
+ if (!RAND_set_rand_method(&fake_rand))
54
+ return 0;
55
+
56
+ return 1;
57
+}
58
59
-static const unsigned char P_256_qy[] = {
60
- 0xb3, 0x05, 0x0d, 0xd0, 0xdc, 0xf7, 0x40, 0xe6, 0xf9, 0xd8, 0x6d, 0x7b,
61
- 0x63, 0xca, 0x97, 0xe6, 0x12, 0xf9, 0xd4, 0x18, 0x59, 0xbe, 0xb2, 0x5e,
62
- 0x4a, 0x6a, 0x77, 0x23, 0xf4, 0x11, 0x9d, 0xeb
63
-};
64
+static int restore_rand(void)
65
+{
66
+ if (!RAND_set_rand_method(old_rand))
67
+ return 0;
68
+
69
+ return 1;
70
+}
71
+
72
+static int fbytes(unsigned char *buf, int num)
73
+{
74
+ int ret = 0;
75
+ static int fbytes_counter = 0;
76
+
77
+ if (use_fake == 0)
78
+ return old_rand->bytes(buf, num);
79
+
80
+ use_fake = 0;
81
+
82
+ if (fbytes_counter >= OSSL_NELEM(numbers))
83
+ goto err;
84
+
85
+ if (numbers_len[fbytes_counter] > num)
86
+ goto err;
87
+
88
+ /* first zero out the buffer */
89
+ memset(buf, 0, num);
90
+
91
+ /* Now set the "random" values */
92
+ memcpy(buf + (num - numbers_len[fbytes_counter]), numbers[fbytes_counter], numbers_len[fbytes_counter]);
93
+
94
+ fbytes_counter = (fbytes_counter + 1) % OSSL_NELEM(numbers);
95
+ ret = 1;
96
+err:
97
+ return ret;
98
+}
99
+
100
+
101
+
102
+/*-
103
+ * NIST CAVP ECDSA KATs
104
+ * 2 X9.62 KATs; one for prime fields and one for binary fields.
105
+ *
106
+ * Taken from:
107
+ * https://csrc.nist.gov/CSRC/media/Projects/Cryptographic-Algorithm-Validation-Program/documents/dss/186-3ecdsatestvectors.zip
108
+ */
109
110
typedef struct {
111
- int curve;
112
- const char *name;
113
- const unsigned char *x;
114
- size_t xlen;
115
- const unsigned char *y;
116
- size_t ylen;
117
- const unsigned char *d;
118
- size_t dlen;
119
-} EC_SELFTEST_DATA;
120
-
121
-# define make_ecdsa_test(nid, pr) { nid, pr##_name, \
122
- pr##_qx, sizeof(pr##_qx), \
123
- pr##_qy, sizeof(pr##_qy), \
124
- pr##_d, sizeof(pr##_d)}
125
-
126
-static EC_SELFTEST_DATA test_ec_data[] = {
127
- make_ecdsa_test(NID_X9_62_prime256v1, P_256),
128
-};
129
+ const int nid; /* curve NID */
130
+ const int md_nid; /* hash function NID */
131
+ const unsigned char *msg; /* message to sign */
132
+ size_t msglen;
133
+ const unsigned char *d; /* ECDSA private key */
134
+ size_t dlen;
135
+ const unsigned char *Q; /* ECDSA public key: (Qx,Qy) */
136
+ size_t Qlen;
137
+ const unsigned char *k; /* ECDSA nonce */
138
+ size_t klen;
139
+ const unsigned char *r; /* ECDSA signature (r,s) */
140
+ size_t rlen;
141
+ const unsigned char *s;
142
+ size_t slen;
143
+} ECDSA_KAT_SELFTEST_DATA;
144
145
-int FIPS_selftest_ecdsa()
146
-{
147
- EC_KEY *ec = NULL;
148
- BIGNUM *x = NULL, *y = NULL, *d = NULL;
149
- EVP_PKEY *pk = NULL;
150
- int rv = 0;
151
- size_t i;
152
153
- for (i = 0; i < sizeof(test_ec_data) / sizeof(EC_SELFTEST_DATA); i++) {
154
- EC_SELFTEST_DATA *ecd = test_ec_data + i;
155
+static const unsigned char data1_msg[] = {
156
+ 0x59, 0x05, 0x23, 0x88, 0x77, 0xc7, 0x74, 0x21,
157
+ 0xf7, 0x3e, 0x43, 0xee, 0x3d, 0xa6, 0xf2, 0xd9,
158
+ 0xe2, 0xcc, 0xad, 0x5f, 0xc9, 0x42, 0xdc, 0xec,
159
+ 0x0c, 0xbd, 0x25, 0x48, 0x29, 0x35, 0xfa, 0xaf,
160
+ 0x41, 0x69, 0x83, 0xfe, 0x16, 0x5b, 0x1a, 0x04,
161
+ 0x5e, 0xe2, 0xbc, 0xd2, 0xe6, 0xdc, 0xa3, 0xbd,
162
+ 0xf4, 0x6c, 0x43, 0x10, 0xa7, 0x46, 0x1f, 0x9a,
163
+ 0x37, 0x96, 0x0c, 0xa6, 0x72, 0xd3, 0xfe, 0xb5,
164
+ 0x47, 0x3e, 0x25, 0x36, 0x05, 0xfb, 0x1d, 0xdf,
165
+ 0xd2, 0x80, 0x65, 0xb5, 0x3c, 0xb5, 0x85, 0x8a,
166
+ 0x8a, 0xd2, 0x81, 0x75, 0xbf, 0x9b, 0xd3, 0x86,
167
+ 0xa5, 0xe4, 0x71, 0xea, 0x7a, 0x65, 0xc1, 0x7c,
168
+ 0xc9, 0x34, 0xa9, 0xd7, 0x91, 0xe9, 0x14, 0x91,
169
+ 0xeb, 0x37, 0x54, 0xd0, 0x37, 0x99, 0x79, 0x0f,
170
+ 0xe2, 0xd3, 0x08, 0xd1, 0x61, 0x46, 0xd5, 0xc9,
171
+ 0xb0, 0xd0, 0xde, 0xbd, 0x97, 0xd7, 0x9c, 0xe8
172
+};
173
174
- x = BN_bin2bn(ecd->x, ecd->xlen, x);
175
- y = BN_bin2bn(ecd->y, ecd->ylen, y);
176
- d = BN_bin2bn(ecd->d, ecd->dlen, d);
177
+static const unsigned char data1_d[] = {
178
+ 0x51, 0x9b, 0x42, 0x3d, 0x71, 0x5f, 0x8b, 0x58,
179
+ 0x1f, 0x4f, 0xa8, 0xee, 0x59, 0xf4, 0x77, 0x1a,
180
+ 0x5b, 0x44, 0xc8, 0x13, 0x0b, 0x4e, 0x3e, 0xac,
181
+ 0xca, 0x54, 0xa5, 0x6d, 0xda, 0x72, 0xb4, 0x64
182
+};
183
184
- if (!x || !y || !d)
185
- goto err;
186
+static const unsigned char data1_Q[] = {
187
+ 0x04, 0x0c, 0xec, 0x02, 0x8e, 0xe0, 0x8d, 0x09,
188
+ 0xe0, 0x26, 0x72, 0xa6, 0x83, 0x10, 0x81, 0x43,
189
+ 0x54, 0xf9, 0xea, 0xbf, 0xff, 0x0d, 0xe6, 0xda,
190
+ 0xcc, 0x1c, 0xd3, 0xa7, 0x74, 0x49, 0x60, 0x76,
191
+ 0xae, 0xef, 0xf4, 0x71, 0xfb, 0xa0, 0x40, 0x98,
192
+ 0x97, 0xb6, 0xa4, 0x8e, 0x88, 0x01, 0xad, 0x12,
193
+ 0xf9, 0x5d, 0x00, 0x09, 0xb7, 0x53, 0xcf, 0x8f,
194
+ 0x51, 0xc1, 0x28, 0xbf, 0x6b, 0x0b, 0xd2, 0x7f,
195
+ 0xbd
196
+};
197
198
- ec = EC_KEY_new_by_curve_name(ecd->curve);
199
- if (!ec)
200
- goto err;
201
+static const unsigned char data1_k[] = {
202
+ 0x94, 0xa1, 0xbb, 0xb1, 0x4b, 0x90, 0x6a, 0x61,
203
+ 0xa2, 0x80, 0xf2, 0x45, 0xf9, 0xe9, 0x3c, 0x7f,
204
+ 0x3b, 0x4a, 0x62, 0x47, 0x82, 0x4f, 0x5d, 0x33,
205
+ 0xb9, 0x67, 0x07, 0x87, 0x64, 0x2a, 0x68, 0xde
206
+};
207
208
- if (!EC_KEY_set_public_key_affine_coordinates(ec, x, y))
209
- goto err;
210
+static const unsigned char data1_r[] = {
211
+ 0xe3, 0x95, 0xf6, 0xdb, 0x12, 0x71, 0x90, 0xfa,
212
+ 0x70, 0xa6, 0x80, 0xeb, 0xf6, 0x8a, 0x18, 0x35,
213
+ 0x6f, 0xef, 0xf2, 0x36, 0x65, 0xb9, 0x31, 0xc3,
214
+ 0xa2, 0x14, 0x80, 0xdf, 0x86, 0xc4, 0xec, 0xbc
215
+};
216
217
- if (!EC_KEY_set_private_key(ec, d))
218
- goto err;
219
+static const unsigned char data1_s[] = {
220
+ 0xa5, 0x01, 0x04, 0x78, 0x93, 0xd9, 0x60, 0xcc,
221
+ 0x20, 0xce, 0xbd, 0xbb, 0x6f, 0x79, 0xb9, 0x7e,
222
+ 0x45, 0x23, 0x80, 0x73, 0x87, 0x83, 0x53, 0x63,
223
+ 0xe3, 0x80, 0x2b, 0x68, 0xcf, 0x32, 0xa1, 0xa2
224
+};
225
226
- if ((pk = EVP_PKEY_new()) == NULL)
227
- goto err;
228
229
- EVP_PKEY_assign_EC_KEY(pk, ec);
230
+# define make_ecdsa_kat_test(nid, md_nid, pr) { \
231
+nid, md_nid, \
232
+pr##_msg, sizeof(pr##_msg), \
233
+pr##_d, sizeof(pr##_d), \
234
+pr##_Q, sizeof(pr##_Q), \
235
+pr##_k, sizeof(pr##_k), \
236
+pr##_r, sizeof(pr##_r), \
237
+pr##_s, sizeof(pr##_s) \
238
+}
239
240
- if (!fips_pkey_signature_test(pk, NULL, 0,
241
- NULL, 0, EVP_sha256(), 0, ecd->name))
242
- goto err;
243
- }
244
+static ECDSA_KAT_SELFTEST_DATA test_ecdsa_data[] = {
245
+ make_ecdsa_kat_test(NID_secp256k1, NID_sha256, data1)
246
+};
247
248
- rv = 1;
249
+int FIPS_selftest_ecdsa()
250
+{
251
+ int rv;
252
+ size_t i, siglen, p_len;
253
+
254
+ for (i = 0; i < sizeof(test_ecdsa_data) / sizeof(ECDSA_KAT_SELFTEST_DATA); i++) {
255
+ EC_KEY *ec = NULL;
256
+ BIGNUM *r = NULL, *s = NULL;
257
+ BIGNUM *sig_r = NULL, *sig_s = NULL;
258
+ EVP_PKEY *pk = NULL;
259
+ unsigned char *sig = NULL;
260
+ unsigned char *tsig = NULL;
261
+ unsigned char *p_buf = NULL;
262
+ ECDSA_SIG *dsa_sig = NULL;
263
+ rv = 0;
264
+
265
+ ECDSA_KAT_SELFTEST_DATA *ecd = test_ecdsa_data + i;
266
+
267
+ /* Create the Message Digest Context */
268
+ EVP_MD_CTX *mdctx = EVP_MD_CTX_new();
269
+ if (!mdctx) goto err;
270
+
271
+ r = BN_bin2bn(ecd->r, ecd->rlen, r);
272
+ s = BN_bin2bn(ecd->s, ecd->slen, s);
273
+
274
+ if (!r || !s)
275
+ goto err;
276
+
277
+ /* d[] will be used to generate a key. */
278
+ /* k[] will be used for signature generation. */
279
+ numbers[0] = ecd->d;
280
+ numbers_len[0] = ecd->dlen;
281
+ numbers[1] = ecd->k;
282
+ numbers_len[1] = ecd->klen;
283
+ /* swap the RNG source */
284
+ if (!change_rand())
285
+ goto err;
286
+
287
+ ec = EC_KEY_new_by_curve_name(ecd->nid);
288
+ if (!ec)
289
+ goto err;
290
+
291
+ /* Use d[] to generate key. */
292
+ use_fake = 1;
293
+ if (EC_KEY_generate_key(ec) != 1)
294
+ goto err;
295
+
296
+ if ((pk = EVP_PKEY_new()) == NULL)
297
+ goto err;
298
+
299
+ EVP_PKEY_assign_EC_KEY(pk, ec);
300
+
301
+ p_len = EC_KEY_key2buf(ec, POINT_CONVERSION_UNCOMPRESSED, &p_buf, NULL);
302
+ if (!p_len)
303
+ goto err;
304
+
305
+ /* Make sure generated public key matches */
306
+ if (p_len != ecd->Qlen)
307
+ goto err;
308
+ if (memcmp(p_buf, ecd->Q, p_len))
309
+ goto err;
310
+
311
+ /* Initialise the DigestSign operation */
312
+ if(1 != EVP_DigestSignInit(mdctx, NULL, EVP_get_digestbynid(ecd->md_nid), NULL, pk))
313
+ goto err;
314
+
315
+ /* Call update with the message */
316
+ if(1 != EVP_DigestSignUpdate(mdctx, ecd->msg, ecd->msglen))
317
+ goto err;
318
+
319
+ /* Finalise the DigestSign operation */
320
+ /* First call EVP_DigestSignFinal with a NULL sig parameter to */
321
+ /* obtain the length of the signature. Length is returned in slen */
322
+ if(1 != EVP_DigestSignFinal(mdctx, NULL, &siglen))
323
+ goto err;
324
+
325
+ /* Allocate memory for the signature based on size in slen */
326
+ if(!(sig = OPENSSL_malloc(siglen)))
327
+ goto err;
328
+
329
+ /* Use k[] for signature. */
330
+ use_fake = 1;
331
+
332
+ /* Obtain the signature */
333
+ if(1 != EVP_DigestSignFinal(mdctx, sig, &siglen))
334
+ goto err;
335
336
- err:
337
+ /* extract r and s */
338
+ tsig = sig;
339
+ dsa_sig = d2i_ECDSA_SIG(NULL, &tsig, siglen);
340
+ if (dsa_sig == NULL)
341
+ goto err;
342
+
343
+ sig_r = ECDSA_SIG_get0_r(dsa_sig);
344
+ sig_s = ECDSA_SIG_get0_s(dsa_sig);
345
+ if ((sig_r == NULL) || (sig_s == NULL))
346
+ goto err;
347
348
- if (x)
349
- BN_clear_free(x);
350
- if (y)
351
- BN_clear_free(y);
352
- if (d)
353
- BN_clear_free(d);
354
+ /* Compare r and s against known. */
355
+ if ((BN_cmp(sig_r, r) != 0) || (BN_cmp(sig_s, s) != 0))
356
+ goto err;
357
+
358
+ /* Verify signature */
359
+ if(1 != EVP_DigestVerifyInit(mdctx, NULL, EVP_get_digestbynid(ecd->md_nid), NULL, pk))
360
+ goto err;
361
+
362
+ if (EVP_DigestVerify(mdctx, sig, siglen, ecd->msg, ecd->msglen) != 1)
363
+ goto err;
364
+
365
+ if (1 != restore_rand())
366
+ goto err;
367
+
368
+ /* Success */
369
+ rv = 1;
370
+
371
+
372
+ err:
373
+
374
+ if (mdctx)
375
+ EVP_MD_CTX_free(mdctx);
376
+ if (r)
377
+ BN_clear_free(r);
378
+ if (s)
379
+ BN_clear_free(s);
380
+ if (sig)
381
+ OPENSSL_free(sig);
382
+ if (dsa_sig)
383
+ ECDSA_SIG_free(dsa_sig);
384
+ if (p_buf)
385
+ OPENSSL_free(p_buf);
386
if (pk)
387
- EVP_PKEY_free(pk);
388
+ EVP_PKEY_free(pk);
389
else if (ec)
390
- EC_KEY_free(ec);
391
-
392
- return rv;
393
+ EC_KEY_free(ec);
394
+
395
+ if (rv != 1) {
396
+ FIPSerr(FIPS_F_FIPS_SELFTEST_ECDSA, FIPS_R_SELFTEST_FAILED);
397
+ break;
398
+ }
399
+
400
+ }
401
402
+ return rv;
403
+
404
}
405
406
+
407
#endif
408