Deleted Added
full compact
schnorr.c (192595) schnorr.c (197679)
1/* $OpenBSD: schnorr.c,v 1.2 2009/02/18 04:31:21 djm Exp $ */
2/* $FreeBSD: head/crypto/openssh/schnorr.c 192595 2009-05-22 18:46:28Z des $ */
1/* $OpenBSD: schnorr.c,v 1.3 2009/03/05 07:18:19 djm Exp $ */
2/* $FreeBSD: head/crypto/openssh/schnorr.c 197679 2009-10-01 17:12:52Z des $ */
3/*
4 * Copyright (c) 2008 Damien Miller. All rights reserved.
5 *
6 * Permission to use, copy, modify, and distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES

--- 25 unchanged lines hidden (view full) ---

36
37#include <openssl/evp.h>
38#include <openssl/bn.h>
39
40#include "xmalloc.h"
41#include "buffer.h"
42#include "log.h"
43
3/*
4 * Copyright (c) 2008 Damien Miller. All rights reserved.
5 *
6 * Permission to use, copy, modify, and distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES

--- 25 unchanged lines hidden (view full) ---

36
37#include <openssl/evp.h>
38#include <openssl/bn.h>
39
40#include "xmalloc.h"
41#include "buffer.h"
42#include "log.h"
43
44#include "jpake.h"
44#include "schnorr.h"
45
46#ifdef JPAKE
47
45
46#ifdef JPAKE
47
48#include "openbsd-compat/openssl-compat.h"
49
48/* #define SCHNORR_DEBUG */ /* Privacy-violating debugging */
49/* #define SCHNORR_MAIN */ /* Include main() selftest */
50
50/* #define SCHNORR_DEBUG */ /* Privacy-violating debugging */
51/* #define SCHNORR_MAIN */ /* Include main() selftest */
52
51/* XXX */
52/* Parametise signature hash? (sha256, sha1, etc.) */
53/* Signature format - include type name, hash type, group params? */
54
55#ifndef SCHNORR_DEBUG
56# define SCHNORR_DEBUG_BN(a)
57# define SCHNORR_DEBUG_BUF(a)
58#else
53#ifndef SCHNORR_DEBUG
54# define SCHNORR_DEBUG_BN(a)
55# define SCHNORR_DEBUG_BUF(a)
56#else
59# define SCHNORR_DEBUG_BN(a) jpake_debug3_bn a
60# define SCHNORR_DEBUG_BUF(a) jpake_debug3_buf a
57# define SCHNORR_DEBUG_BN(a) debug3_bn a
58# define SCHNORR_DEBUG_BUF(a) debug3_buf a
61#endif /* SCHNORR_DEBUG */
62
63/*
64 * Calculate hash component of Schnorr signature H(g || g^v || g^x || id)
59#endif /* SCHNORR_DEBUG */
60
61/*
62 * Calculate hash component of Schnorr signature H(g || g^v || g^x || id)
65 * using SHA1. Returns signature as bignum or NULL on error.
63 * using the hash function defined by "evp_md". Returns signature as
64 * bignum or NULL on error.
66 */
67static BIGNUM *
68schnorr_hash(const BIGNUM *p, const BIGNUM *q, const BIGNUM *g,
65 */
66static BIGNUM *
67schnorr_hash(const BIGNUM *p, const BIGNUM *q, const BIGNUM *g,
69 const BIGNUM *g_v, const BIGNUM *g_x,
68 const EVP_MD *evp_md, const BIGNUM *g_v, const BIGNUM *g_x,
70 const u_char *id, u_int idlen)
71{
72 u_char *digest;
73 u_int digest_len;
74 BIGNUM *h;
69 const u_char *id, u_int idlen)
70{
71 u_char *digest;
72 u_int digest_len;
73 BIGNUM *h;
75 EVP_MD_CTX evp_md_ctx;
76 Buffer b;
77 int success = -1;
78
79 if ((h = BN_new()) == NULL) {
80 error("%s: BN_new", __func__);
81 return NULL;
82 }
83
84 buffer_init(&b);
74 Buffer b;
75 int success = -1;
76
77 if ((h = BN_new()) == NULL) {
78 error("%s: BN_new", __func__);
79 return NULL;
80 }
81
82 buffer_init(&b);
85 EVP_MD_CTX_init(&evp_md_ctx);
86
87 /* h = H(g || p || q || g^v || g^x || id) */
88 buffer_put_bignum2(&b, g);
89 buffer_put_bignum2(&b, p);
90 buffer_put_bignum2(&b, q);
91 buffer_put_bignum2(&b, g_v);
92 buffer_put_bignum2(&b, g_x);
93 buffer_put_string(&b, id, idlen);
94
95 SCHNORR_DEBUG_BUF((buffer_ptr(&b), buffer_len(&b),
96 "%s: hashblob", __func__));
83
84 /* h = H(g || p || q || g^v || g^x || id) */
85 buffer_put_bignum2(&b, g);
86 buffer_put_bignum2(&b, p);
87 buffer_put_bignum2(&b, q);
88 buffer_put_bignum2(&b, g_v);
89 buffer_put_bignum2(&b, g_x);
90 buffer_put_string(&b, id, idlen);
91
92 SCHNORR_DEBUG_BUF((buffer_ptr(&b), buffer_len(&b),
93 "%s: hashblob", __func__));
97 if (hash_buffer(buffer_ptr(&b), buffer_len(&b), EVP_sha256(),
94 if (hash_buffer(buffer_ptr(&b), buffer_len(&b), evp_md,
98 &digest, &digest_len) != 0) {
99 error("%s: hash_buffer", __func__);
100 goto out;
101 }
102 if (BN_bin2bn(digest, (int)digest_len, h) == NULL) {
103 error("%s: BN_bin2bn", __func__);
104 goto out;
105 }
106 success = 0;
107 SCHNORR_DEBUG_BN((h, "%s: h = ", __func__));
108 out:
109 buffer_free(&b);
95 &digest, &digest_len) != 0) {
96 error("%s: hash_buffer", __func__);
97 goto out;
98 }
99 if (BN_bin2bn(digest, (int)digest_len, h) == NULL) {
100 error("%s: BN_bin2bn", __func__);
101 goto out;
102 }
103 success = 0;
104 SCHNORR_DEBUG_BN((h, "%s: h = ", __func__));
105 out:
106 buffer_free(&b);
110 EVP_MD_CTX_cleanup(&evp_md_ctx);
111 bzero(digest, digest_len);
112 xfree(digest);
113 digest_len = 0;
114 if (success == 0)
115 return h;
116 BN_clear_free(h);
117 return NULL;
118}
119
120/*
121 * Generate Schnorr signature to prove knowledge of private value 'x' used
122 * in public exponent g^x, under group defined by 'grp_p', 'grp_q' and 'grp_g'
107 bzero(digest, digest_len);
108 xfree(digest);
109 digest_len = 0;
110 if (success == 0)
111 return h;
112 BN_clear_free(h);
113 return NULL;
114}
115
116/*
117 * Generate Schnorr signature to prove knowledge of private value 'x' used
118 * in public exponent g^x, under group defined by 'grp_p', 'grp_q' and 'grp_g'
119 * using the hash function "evp_md".
123 * 'idlen' bytes from 'id' will be included in the signature hash as an anti-
124 * replay salt.
120 * 'idlen' bytes from 'id' will be included in the signature hash as an anti-
121 * replay salt.
125 * On success, 0 is returned and *siglen bytes of signature are returned in
126 * *sig (caller to free). Returns -1 on failure.
122 *
123 * On success, 0 is returned. The signature values are returned as *e_p
124 * (g^v mod p) and *r_p (v - xh mod q). The caller must free these values.
125 * On failure, -1 is returned.
127 */
128int
129schnorr_sign(const BIGNUM *grp_p, const BIGNUM *grp_q, const BIGNUM *grp_g,
126 */
127int
128schnorr_sign(const BIGNUM *grp_p, const BIGNUM *grp_q, const BIGNUM *grp_g,
130 const BIGNUM *x, const BIGNUM *g_x, const u_char *id, u_int idlen,
131 u_char **sig, u_int *siglen)
129 const EVP_MD *evp_md, const BIGNUM *x, const BIGNUM *g_x,
130 const u_char *id, u_int idlen, BIGNUM **r_p, BIGNUM **e_p)
132{
133 int success = -1;
131{
132 int success = -1;
134 Buffer b;
135 BIGNUM *h, *tmp, *v, *g_v, *r;
136 BN_CTX *bn_ctx;
137
138 SCHNORR_DEBUG_BN((x, "%s: x = ", __func__));
139 SCHNORR_DEBUG_BN((g_x, "%s: g_x = ", __func__));
140
141 /* Avoid degenerate cases: g^0 yields a spoofable signature */
142 if (BN_cmp(g_x, BN_value_one()) <= 0) {

--- 26 unchanged lines hidden (view full) ---

169 /* g_v = g^v mod p */
170 if (BN_mod_exp(g_v, grp_g, v, grp_p, bn_ctx) == -1) {
171 error("%s: BN_mod_exp (g^v mod p)", __func__);
172 goto out;
173 }
174 SCHNORR_DEBUG_BN((g_v, "%s: g_v = ", __func__));
175
176 /* h = H(g || g^v || g^x || id) */
133 BIGNUM *h, *tmp, *v, *g_v, *r;
134 BN_CTX *bn_ctx;
135
136 SCHNORR_DEBUG_BN((x, "%s: x = ", __func__));
137 SCHNORR_DEBUG_BN((g_x, "%s: g_x = ", __func__));
138
139 /* Avoid degenerate cases: g^0 yields a spoofable signature */
140 if (BN_cmp(g_x, BN_value_one()) <= 0) {

--- 26 unchanged lines hidden (view full) ---

167 /* g_v = g^v mod p */
168 if (BN_mod_exp(g_v, grp_g, v, grp_p, bn_ctx) == -1) {
169 error("%s: BN_mod_exp (g^v mod p)", __func__);
170 goto out;
171 }
172 SCHNORR_DEBUG_BN((g_v, "%s: g_v = ", __func__));
173
174 /* h = H(g || g^v || g^x || id) */
177 if ((h = schnorr_hash(grp_p, grp_q, grp_g, g_v, g_x,
175 if ((h = schnorr_hash(grp_p, grp_q, grp_g, evp_md, g_v, g_x,
178 id, idlen)) == NULL) {
179 error("%s: schnorr_hash failed", __func__);
180 goto out;
181 }
182
183 /* r = v - xh mod q */
184 if (BN_mod_mul(tmp, x, h, grp_q, bn_ctx) == -1) {
185 error("%s: BN_mod_mul (tmp = xv mod q)", __func__);
186 goto out;
187 }
188 if (BN_mod_sub(r, v, tmp, grp_q, bn_ctx) == -1) {
189 error("%s: BN_mod_mul (r = v - tmp)", __func__);
190 goto out;
191 }
176 id, idlen)) == NULL) {
177 error("%s: schnorr_hash failed", __func__);
178 goto out;
179 }
180
181 /* r = v - xh mod q */
182 if (BN_mod_mul(tmp, x, h, grp_q, bn_ctx) == -1) {
183 error("%s: BN_mod_mul (tmp = xv mod q)", __func__);
184 goto out;
185 }
186 if (BN_mod_sub(r, v, tmp, grp_q, bn_ctx) == -1) {
187 error("%s: BN_mod_mul (r = v - tmp)", __func__);
188 goto out;
189 }
190 SCHNORR_DEBUG_BN((g_v, "%s: e = ", __func__));
192 SCHNORR_DEBUG_BN((r, "%s: r = ", __func__));
193
191 SCHNORR_DEBUG_BN((r, "%s: r = ", __func__));
192
194 /* Signature is (g_v, r) */
193 *e_p = g_v;
194 *r_p = r;
195
196 success = 0;
197 out:
198 BN_CTX_free(bn_ctx);
199 if (h != NULL)
200 BN_clear_free(h);
201 if (v != NULL)
202 BN_clear_free(v);
203 BN_clear_free(tmp);
204
205 return success;
206}
207
208/*
209 * Generate Schnorr signature to prove knowledge of private value 'x' used
210 * in public exponent g^x, under group defined by 'grp_p', 'grp_q' and 'grp_g'
211 * using a SHA256 hash.
212 * 'idlen' bytes from 'id' will be included in the signature hash as an anti-
213 * replay salt.
214 * On success, 0 is returned and *siglen bytes of signature are returned in
215 * *sig (caller to free). Returns -1 on failure.
216 */
217int
218schnorr_sign_buf(const BIGNUM *grp_p, const BIGNUM *grp_q, const BIGNUM *grp_g,
219 const BIGNUM *x, const BIGNUM *g_x, const u_char *id, u_int idlen,
220 u_char **sig, u_int *siglen)
221{
222 Buffer b;
223 BIGNUM *r, *e;
224
225 if (schnorr_sign(grp_p, grp_q, grp_g, EVP_sha256(),
226 x, g_x, id, idlen, &r, &e) != 0)
227 return -1;
228
229 /* Signature is (e, r) */
195 buffer_init(&b);
196 /* XXX sigtype-hash as string? */
230 buffer_init(&b);
231 /* XXX sigtype-hash as string? */
197 buffer_put_bignum2(&b, g_v);
232 buffer_put_bignum2(&b, e);
198 buffer_put_bignum2(&b, r);
199 *siglen = buffer_len(&b);
200 *sig = xmalloc(*siglen);
201 memcpy(*sig, buffer_ptr(&b), *siglen);
202 SCHNORR_DEBUG_BUF((buffer_ptr(&b), buffer_len(&b),
203 "%s: sigblob", __func__));
204 buffer_free(&b);
233 buffer_put_bignum2(&b, r);
234 *siglen = buffer_len(&b);
235 *sig = xmalloc(*siglen);
236 memcpy(*sig, buffer_ptr(&b), *siglen);
237 SCHNORR_DEBUG_BUF((buffer_ptr(&b), buffer_len(&b),
238 "%s: sigblob", __func__));
239 buffer_free(&b);
205 success = 0;
206 out:
207 BN_CTX_free(bn_ctx);
208 if (h != NULL)
209 BN_clear_free(h);
210 if (v != NULL)
211 BN_clear_free(v);
240
212 BN_clear_free(r);
241 BN_clear_free(r);
213 BN_clear_free(g_v);
214 BN_clear_free(tmp);
242 BN_clear_free(e);
215
243
216 return success;
244 return 0;
217}
218
219/*
245}
246
247/*
220 * Verify Schnorr signature 'sig' of length 'siglen' against public exponent
221 * g_x (g^x) under group defined by 'grp_p', 'grp_q' and 'grp_g'.
248 * Verify Schnorr signature { r (v - xh mod q), e (g^v mod p) } against
249 * public exponent g_x (g^x) under group defined by 'grp_p', 'grp_q' and
250 * 'grp_g' using hash "evp_md".
222 * Signature hash will be salted with 'idlen' bytes from 'id'.
223 * Returns -1 on failure, 0 on incorrect signature or 1 on matching signature.
224 */
225int
226schnorr_verify(const BIGNUM *grp_p, const BIGNUM *grp_q, const BIGNUM *grp_g,
251 * Signature hash will be salted with 'idlen' bytes from 'id'.
252 * Returns -1 on failure, 0 on incorrect signature or 1 on matching signature.
253 */
254int
255schnorr_verify(const BIGNUM *grp_p, const BIGNUM *grp_q, const BIGNUM *grp_g,
227 const BIGNUM *g_x, const u_char *id, u_int idlen,
228 const u_char *sig, u_int siglen)
256 const EVP_MD *evp_md, const BIGNUM *g_x, const u_char *id, u_int idlen,
257 const BIGNUM *r, const BIGNUM *e)
229{
230 int success = -1;
258{
259 int success = -1;
231 Buffer b;
232 BIGNUM *g_v, *h, *r, *g_xh, *g_r, *expected;
260 BIGNUM *h, *g_xh, *g_r, *expected;
233 BN_CTX *bn_ctx;
261 BN_CTX *bn_ctx;
234 u_int rlen;
235
236 SCHNORR_DEBUG_BN((g_x, "%s: g_x = ", __func__));
237
238 /* Avoid degenerate cases: g^0 yields a spoofable signature */
239 if (BN_cmp(g_x, BN_value_one()) <= 0) {
240 error("%s: g_x < 1", __func__);
241 return -1;
242 }
243
262
263 SCHNORR_DEBUG_BN((g_x, "%s: g_x = ", __func__));
264
265 /* Avoid degenerate cases: g^0 yields a spoofable signature */
266 if (BN_cmp(g_x, BN_value_one()) <= 0) {
267 error("%s: g_x < 1", __func__);
268 return -1;
269 }
270
244 g_v = h = r = g_xh = g_r = expected = NULL;
271 h = g_xh = g_r = expected = NULL;
245 if ((bn_ctx = BN_CTX_new()) == NULL) {
246 error("%s: BN_CTX_new", __func__);
247 goto out;
248 }
272 if ((bn_ctx = BN_CTX_new()) == NULL) {
273 error("%s: BN_CTX_new", __func__);
274 goto out;
275 }
249 if ((g_v = BN_new()) == NULL ||
250 (r = BN_new()) == NULL ||
251 (g_xh = BN_new()) == NULL ||
276 if ((g_xh = BN_new()) == NULL ||
252 (g_r = BN_new()) == NULL ||
253 (expected = BN_new()) == NULL) {
254 error("%s: BN_new", __func__);
255 goto out;
256 }
257
277 (g_r = BN_new()) == NULL ||
278 (expected = BN_new()) == NULL) {
279 error("%s: BN_new", __func__);
280 goto out;
281 }
282
258 /* Extract g^v and r from signature blob */
259 buffer_init(&b);
260 buffer_append(&b, sig, siglen);
261 SCHNORR_DEBUG_BUF((buffer_ptr(&b), buffer_len(&b),
262 "%s: sigblob", __func__));
263 buffer_get_bignum2(&b, g_v);
264 buffer_get_bignum2(&b, r);
265 rlen = buffer_len(&b);
266 buffer_free(&b);
267 if (rlen != 0) {
268 error("%s: remaining bytes in signature %d", __func__, rlen);
269 goto out;
270 }
271 buffer_free(&b);
272 SCHNORR_DEBUG_BN((g_v, "%s: g_v = ", __func__));
283 SCHNORR_DEBUG_BN((e, "%s: e = ", __func__));
273 SCHNORR_DEBUG_BN((r, "%s: r = ", __func__));
274
275 /* h = H(g || g^v || g^x || id) */
284 SCHNORR_DEBUG_BN((r, "%s: r = ", __func__));
285
286 /* h = H(g || g^v || g^x || id) */
276 if ((h = schnorr_hash(grp_p, grp_q, grp_g, g_v, g_x,
287 if ((h = schnorr_hash(grp_p, grp_q, grp_g, evp_md, e, g_x,
277 id, idlen)) == NULL) {
278 error("%s: schnorr_hash failed", __func__);
279 goto out;
280 }
281
282 /* g_xh = (g^x)^h */
283 if (BN_mod_exp(g_xh, g_x, h, grp_p, bn_ctx) == -1) {
284 error("%s: BN_mod_exp (g_x^h mod p)", __func__);

--- 10 unchanged lines hidden (view full) ---

295
296 /* expected = g^r * g_xh */
297 if (BN_mod_mul(expected, g_r, g_xh, grp_p, bn_ctx) == -1) {
298 error("%s: BN_mod_mul (expected = g_r mod p)", __func__);
299 goto out;
300 }
301 SCHNORR_DEBUG_BN((expected, "%s: expected = ", __func__));
302
288 id, idlen)) == NULL) {
289 error("%s: schnorr_hash failed", __func__);
290 goto out;
291 }
292
293 /* g_xh = (g^x)^h */
294 if (BN_mod_exp(g_xh, g_x, h, grp_p, bn_ctx) == -1) {
295 error("%s: BN_mod_exp (g_x^h mod p)", __func__);

--- 10 unchanged lines hidden (view full) ---

306
307 /* expected = g^r * g_xh */
308 if (BN_mod_mul(expected, g_r, g_xh, grp_p, bn_ctx) == -1) {
309 error("%s: BN_mod_mul (expected = g_r mod p)", __func__);
310 goto out;
311 }
312 SCHNORR_DEBUG_BN((expected, "%s: expected = ", __func__));
313
303 /* Check g_v == expected */
304 success = BN_cmp(expected, g_v) == 0;
314 /* Check e == expected */
315 success = BN_cmp(expected, e) == 0;
305 out:
306 BN_CTX_free(bn_ctx);
307 if (h != NULL)
308 BN_clear_free(h);
316 out:
317 BN_CTX_free(bn_ctx);
318 if (h != NULL)
319 BN_clear_free(h);
309 BN_clear_free(g_v);
310 BN_clear_free(r);
311 BN_clear_free(g_xh);
312 BN_clear_free(g_r);
313 BN_clear_free(expected);
314 return success;
315}
316
320 BN_clear_free(g_xh);
321 BN_clear_free(g_r);
322 BN_clear_free(expected);
323 return success;
324}
325
326/*
327 * Verify Schnorr signature 'sig' of length 'siglen' against public exponent
328 * g_x (g^x) under group defined by 'grp_p', 'grp_q' and 'grp_g' using a
329 * SHA256 hash.
330 * Signature hash will be salted with 'idlen' bytes from 'id'.
331 * Returns -1 on failure, 0 on incorrect signature or 1 on matching signature.
332 */
333int
334schnorr_verify_buf(const BIGNUM *grp_p, const BIGNUM *grp_q,
335 const BIGNUM *grp_g,
336 const BIGNUM *g_x, const u_char *id, u_int idlen,
337 const u_char *sig, u_int siglen)
338{
339 Buffer b;
340 int ret = -1;
341 u_int rlen;
342 BIGNUM *r, *e;
343
344 e = r = NULL;
345 if ((e = BN_new()) == NULL ||
346 (r = BN_new()) == NULL) {
347 error("%s: BN_new", __func__);
348 goto out;
349 }
350
351 /* Extract g^v and r from signature blob */
352 buffer_init(&b);
353 buffer_append(&b, sig, siglen);
354 SCHNORR_DEBUG_BUF((buffer_ptr(&b), buffer_len(&b),
355 "%s: sigblob", __func__));
356 buffer_get_bignum2(&b, e);
357 buffer_get_bignum2(&b, r);
358 rlen = buffer_len(&b);
359 buffer_free(&b);
360 if (rlen != 0) {
361 error("%s: remaining bytes in signature %d", __func__, rlen);
362 goto out;
363 }
364
365 ret = schnorr_verify(grp_p, grp_q, grp_g, EVP_sha256(),
366 g_x, id, idlen, r, e);
367 out:
368 BN_clear_free(e);
369 BN_clear_free(r);
370
371 return ret;
372}
373
374/* Helper functions */
375
376/*
377 * Generate uniformly distributed random number in range (1, high).
378 * Return number on success, NULL on failure.
379 */
380BIGNUM *
381bn_rand_range_gt_one(const BIGNUM *high)
382{
383 BIGNUM *r, *tmp;
384 int success = -1;
385
386 if ((tmp = BN_new()) == NULL) {
387 error("%s: BN_new", __func__);
388 return NULL;
389 }
390 if ((r = BN_new()) == NULL) {
391 error("%s: BN_new failed", __func__);
392 goto out;
393 }
394 if (BN_set_word(tmp, 2) != 1) {
395 error("%s: BN_set_word(tmp, 2)", __func__);
396 goto out;
397 }
398 if (BN_sub(tmp, high, tmp) == -1) {
399 error("%s: BN_sub failed (tmp = high - 2)", __func__);
400 goto out;
401 }
402 if (BN_rand_range(r, tmp) == -1) {
403 error("%s: BN_rand_range failed", __func__);
404 goto out;
405 }
406 if (BN_set_word(tmp, 2) != 1) {
407 error("%s: BN_set_word(tmp, 2)", __func__);
408 goto out;
409 }
410 if (BN_add(r, r, tmp) == -1) {
411 error("%s: BN_add failed (r = r + 2)", __func__);
412 goto out;
413 }
414 success = 0;
415 out:
416 BN_clear_free(tmp);
417 if (success == 0)
418 return r;
419 BN_clear_free(r);
420 return NULL;
421}
422
423/*
424 * Hash contents of buffer 'b' with hash 'md'. Returns 0 on success,
425 * with digest via 'digestp' (caller to free) and length via 'lenp'.
426 * Returns -1 on failure.
427 */
428int
429hash_buffer(const u_char *buf, u_int len, const EVP_MD *md,
430 u_char **digestp, u_int *lenp)
431{
432 u_char digest[EVP_MAX_MD_SIZE];
433 u_int digest_len;
434 EVP_MD_CTX evp_md_ctx;
435 int success = -1;
436
437 EVP_MD_CTX_init(&evp_md_ctx);
438
439 if (EVP_DigestInit_ex(&evp_md_ctx, md, NULL) != 1) {
440 error("%s: EVP_DigestInit_ex", __func__);
441 goto out;
442 }
443 if (EVP_DigestUpdate(&evp_md_ctx, buf, len) != 1) {
444 error("%s: EVP_DigestUpdate", __func__);
445 goto out;
446 }
447 if (EVP_DigestFinal_ex(&evp_md_ctx, digest, &digest_len) != 1) {
448 error("%s: EVP_DigestFinal_ex", __func__);
449 goto out;
450 }
451 *digestp = xmalloc(digest_len);
452 *lenp = digest_len;
453 memcpy(*digestp, digest, *lenp);
454 success = 0;
455 out:
456 EVP_MD_CTX_cleanup(&evp_md_ctx);
457 bzero(digest, sizeof(digest));
458 digest_len = 0;
459 return success;
460}
461
462/* print formatted string followed by bignum */
463void
464debug3_bn(const BIGNUM *n, const char *fmt, ...)
465{
466 char *out, *h;
467 va_list args;
468
469 out = NULL;
470 va_start(args, fmt);
471 vasprintf(&out, fmt, args);
472 va_end(args);
473 if (out == NULL)
474 fatal("%s: vasprintf failed", __func__);
475
476 if (n == NULL)
477 debug3("%s(null)", out);
478 else {
479 h = BN_bn2hex(n);
480 debug3("%s0x%s", out, h);
481 free(h);
482 }
483 free(out);
484}
485
486/* print formatted string followed by buffer contents in hex */
487void
488debug3_buf(const u_char *buf, u_int len, const char *fmt, ...)
489{
490 char *out, h[65];
491 u_int i, j;
492 va_list args;
493
494 out = NULL;
495 va_start(args, fmt);
496 vasprintf(&out, fmt, args);
497 va_end(args);
498 if (out == NULL)
499 fatal("%s: vasprintf failed", __func__);
500
501 debug3("%s length %u%s", out, len, buf == NULL ? " (null)" : "");
502 free(out);
503 if (buf == NULL)
504 return;
505
506 *h = '\0';
507 for (i = j = 0; i < len; i++) {
508 snprintf(h + j, sizeof(h) - j, "%02x", buf[i]);
509 j += 2;
510 if (j >= sizeof(h) - 1 || i == len - 1) {
511 debug3(" %s", h);
512 *h = '\0';
513 j = 0;
514 }
515 }
516}
517
518/*
519 * Construct a MODP group from hex strings p (which must be a safe
520 * prime) and g, automatically calculating subgroup q as (p / 2)
521 */
522struct modp_group *
523modp_group_from_g_and_safe_p(const char *grp_g, const char *grp_p)
524{
525 struct modp_group *ret;
526
527 ret = xmalloc(sizeof(*ret));
528 ret->p = ret->q = ret->g = NULL;
529 if (BN_hex2bn(&ret->p, grp_p) == 0 ||
530 BN_hex2bn(&ret->g, grp_g) == 0)
531 fatal("%s: BN_hex2bn", __func__);
532 /* Subgroup order is p/2 (p is a safe prime) */
533 if ((ret->q = BN_new()) == NULL)
534 fatal("%s: BN_new", __func__);
535 if (BN_rshift1(ret->q, ret->p) != 1)
536 fatal("%s: BN_rshift1", __func__);
537
538 return ret;
539}
540
541void
542modp_group_free(struct modp_group *grp)
543{
544 if (grp->g != NULL)
545 BN_clear_free(grp->g);
546 if (grp->p != NULL)
547 BN_clear_free(grp->p);
548 if (grp->q != NULL)
549 BN_clear_free(grp->q);
550 bzero(grp, sizeof(*grp));
551 xfree(grp);
552}
553
554/* main() function for self-test */
555
317#ifdef SCHNORR_MAIN
318static void
319schnorr_selftest_one(const BIGNUM *grp_p, const BIGNUM *grp_q,
320 const BIGNUM *grp_g, const BIGNUM *x)
321{
322 BIGNUM *g_x;
323 u_char *sig;
324 u_int siglen;
325 BN_CTX *bn_ctx;
326
327 if ((bn_ctx = BN_CTX_new()) == NULL)
328 fatal("%s: BN_CTX_new", __func__);
329 if ((g_x = BN_new()) == NULL)
330 fatal("%s: BN_new", __func__);
331
332 if (BN_mod_exp(g_x, grp_g, x, grp_p, bn_ctx) == -1)
333 fatal("%s: g_x", __func__);
556#ifdef SCHNORR_MAIN
557static void
558schnorr_selftest_one(const BIGNUM *grp_p, const BIGNUM *grp_q,
559 const BIGNUM *grp_g, const BIGNUM *x)
560{
561 BIGNUM *g_x;
562 u_char *sig;
563 u_int siglen;
564 BN_CTX *bn_ctx;
565
566 if ((bn_ctx = BN_CTX_new()) == NULL)
567 fatal("%s: BN_CTX_new", __func__);
568 if ((g_x = BN_new()) == NULL)
569 fatal("%s: BN_new", __func__);
570
571 if (BN_mod_exp(g_x, grp_g, x, grp_p, bn_ctx) == -1)
572 fatal("%s: g_x", __func__);
334 if (schnorr_sign(grp_p, grp_q, grp_g, x, g_x, "junk", 4, &sig, &siglen))
573 if (schnorr_sign_buf(grp_p, grp_q, grp_g, x, g_x, "junk", 4,
574 &sig, &siglen))
335 fatal("%s: schnorr_sign", __func__);
575 fatal("%s: schnorr_sign", __func__);
336 if (schnorr_verify(grp_p, grp_q, grp_g, g_x, "junk", 4,
576 if (schnorr_verify_buf(grp_p, grp_q, grp_g, g_x, "junk", 4,
337 sig, siglen) != 1)
338 fatal("%s: verify fail", __func__);
577 sig, siglen) != 1)
578 fatal("%s: verify fail", __func__);
339 if (schnorr_verify(grp_p, grp_q, grp_g, g_x, "JUNK", 4,
579 if (schnorr_verify_buf(grp_p, grp_q, grp_g, g_x, "JUNK", 4,
340 sig, siglen) != 0)
341 fatal("%s: verify should have failed (bad ID)", __func__);
342 sig[4] ^= 1;
580 sig, siglen) != 0)
581 fatal("%s: verify should have failed (bad ID)", __func__);
582 sig[4] ^= 1;
343 if (schnorr_verify(grp_p, grp_q, grp_g, g_x, "junk", 4,
583 if (schnorr_verify_buf(grp_p, grp_q, grp_g, g_x, "junk", 4,
344 sig, siglen) != 0)
345 fatal("%s: verify should have failed (bit error)", __func__);
346 xfree(sig);
347 BN_free(g_x);
348 BN_CTX_free(bn_ctx);
349}
350
351static void
352schnorr_selftest(void)
353{
354 BIGNUM *x;
584 sig, siglen) != 0)
585 fatal("%s: verify should have failed (bit error)", __func__);
586 xfree(sig);
587 BN_free(g_x);
588 BN_CTX_free(bn_ctx);
589}
590
591static void
592schnorr_selftest(void)
593{
594 BIGNUM *x;
355 struct jpake_group *grp;
595 struct modp_group *grp;
356 u_int i;
357 char *hh;
358
359 grp = jpake_default_group();
360 if ((x = BN_new()) == NULL)
361 fatal("%s: BN_new", __func__);
362 SCHNORR_DEBUG_BN((grp->p, "%s: grp->p = ", __func__));
363 SCHNORR_DEBUG_BN((grp->q, "%s: grp->q = ", __func__));

--- 50 unchanged lines hidden ---
596 u_int i;
597 char *hh;
598
599 grp = jpake_default_group();
600 if ((x = BN_new()) == NULL)
601 fatal("%s: BN_new", __func__);
602 SCHNORR_DEBUG_BN((grp->p, "%s: grp->p = ", __func__));
603 SCHNORR_DEBUG_BN((grp->q, "%s: grp->q = ", __func__));

--- 50 unchanged lines hidden ---