summaryrefslogtreecommitdiff
path: root/schnorr.c
diff options
context:
space:
mode:
Diffstat (limited to 'schnorr.c')
-rw-r--r--schnorr.c57
1 files changed, 24 insertions, 33 deletions
diff --git a/schnorr.c b/schnorr.c
index 93822fed4..aa3a57770 100644
--- a/schnorr.c
+++ b/schnorr.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: schnorr.c,v 1.8 2013/11/08 00:39:15 djm Exp $ */ 1/* $OpenBSD: schnorr.c,v 1.9 2014/01/09 23:20:00 djm Exp $ */
2/* 2/*
3 * Copyright (c) 2008 Damien Miller. All rights reserved. 3 * Copyright (c) 2008 Damien Miller. All rights reserved.
4 * 4 *
@@ -41,6 +41,7 @@
41#include "log.h" 41#include "log.h"
42 42
43#include "schnorr.h" 43#include "schnorr.h"
44#include "digest.h"
44 45
45#include "openbsd-compat/openssl-compat.h" 46#include "openbsd-compat/openssl-compat.h"
46 47
@@ -57,12 +58,12 @@
57 58
58/* 59/*
59 * Calculate hash component of Schnorr signature H(g || g^v || g^x || id) 60 * Calculate hash component of Schnorr signature H(g || g^v || g^x || id)
60 * using the hash function defined by "evp_md". Returns signature as 61 * using the hash function defined by "hash_alg". Returns signature as
61 * bignum or NULL on error. 62 * bignum or NULL on error.
62 */ 63 */
63static BIGNUM * 64static BIGNUM *
64schnorr_hash(const BIGNUM *p, const BIGNUM *q, const BIGNUM *g, 65schnorr_hash(const BIGNUM *p, const BIGNUM *q, const BIGNUM *g,
65 const EVP_MD *evp_md, const BIGNUM *g_v, const BIGNUM *g_x, 66 int hash_alg, const BIGNUM *g_v, const BIGNUM *g_x,
66 const u_char *id, u_int idlen) 67 const u_char *id, u_int idlen)
67{ 68{
68 u_char *digest; 69 u_char *digest;
@@ -88,7 +89,7 @@ schnorr_hash(const BIGNUM *p, const BIGNUM *q, const BIGNUM *g,
88 89
89 SCHNORR_DEBUG_BUF((buffer_ptr(&b), buffer_len(&b), 90 SCHNORR_DEBUG_BUF((buffer_ptr(&b), buffer_len(&b),
90 "%s: hashblob", __func__)); 91 "%s: hashblob", __func__));
91 if (hash_buffer(buffer_ptr(&b), buffer_len(&b), evp_md, 92 if (hash_buffer(buffer_ptr(&b), buffer_len(&b), hash_alg,
92 &digest, &digest_len) != 0) { 93 &digest, &digest_len) != 0) {
93 error("%s: hash_buffer", __func__); 94 error("%s: hash_buffer", __func__);
94 goto out; 95 goto out;
@@ -113,7 +114,7 @@ schnorr_hash(const BIGNUM *p, const BIGNUM *q, const BIGNUM *g,
113/* 114/*
114 * Generate Schnorr signature to prove knowledge of private value 'x' used 115 * Generate Schnorr signature to prove knowledge of private value 'x' used
115 * in public exponent g^x, under group defined by 'grp_p', 'grp_q' and 'grp_g' 116 * in public exponent g^x, under group defined by 'grp_p', 'grp_q' and 'grp_g'
116 * using the hash function "evp_md". 117 * using the hash function "hash_alg".
117 * 'idlen' bytes from 'id' will be included in the signature hash as an anti- 118 * 'idlen' bytes from 'id' will be included in the signature hash as an anti-
118 * replay salt. 119 * replay salt.
119 * 120 *
@@ -123,7 +124,7 @@ schnorr_hash(const BIGNUM *p, const BIGNUM *q, const BIGNUM *g,
123 */ 124 */
124int 125int
125schnorr_sign(const BIGNUM *grp_p, const BIGNUM *grp_q, const BIGNUM *grp_g, 126schnorr_sign(const BIGNUM *grp_p, const BIGNUM *grp_q, const BIGNUM *grp_g,
126 const EVP_MD *evp_md, const BIGNUM *x, const BIGNUM *g_x, 127 int hash_alg, const BIGNUM *x, const BIGNUM *g_x,
127 const u_char *id, u_int idlen, BIGNUM **r_p, BIGNUM **e_p) 128 const u_char *id, u_int idlen, BIGNUM **r_p, BIGNUM **e_p)
128{ 129{
129 int success = -1; 130 int success = -1;
@@ -173,7 +174,7 @@ schnorr_sign(const BIGNUM *grp_p, const BIGNUM *grp_q, const BIGNUM *grp_g,
173 SCHNORR_DEBUG_BN((g_v, "%s: g_v = ", __func__)); 174 SCHNORR_DEBUG_BN((g_v, "%s: g_v = ", __func__));
174 175
175 /* h = H(g || g^v || g^x || id) */ 176 /* h = H(g || g^v || g^x || id) */
176 if ((h = schnorr_hash(grp_p, grp_q, grp_g, evp_md, g_v, g_x, 177 if ((h = schnorr_hash(grp_p, grp_q, grp_g, hash_alg, g_v, g_x,
177 id, idlen)) == NULL) { 178 id, idlen)) == NULL) {
178 error("%s: schnorr_hash failed", __func__); 179 error("%s: schnorr_hash failed", __func__);
179 goto out; 180 goto out;
@@ -223,7 +224,7 @@ schnorr_sign_buf(const BIGNUM *grp_p, const BIGNUM *grp_q, const BIGNUM *grp_g,
223 Buffer b; 224 Buffer b;
224 BIGNUM *r, *e; 225 BIGNUM *r, *e;
225 226
226 if (schnorr_sign(grp_p, grp_q, grp_g, EVP_sha256(), 227 if (schnorr_sign(grp_p, grp_q, grp_g, SSH_DIGEST_SHA256,
227 x, g_x, id, idlen, &r, &e) != 0) 228 x, g_x, id, idlen, &r, &e) != 0)
228 return -1; 229 return -1;
229 230
@@ -248,13 +249,13 @@ schnorr_sign_buf(const BIGNUM *grp_p, const BIGNUM *grp_q, const BIGNUM *grp_g,
248/* 249/*
249 * Verify Schnorr signature { r (v - xh mod q), e (g^v mod p) } against 250 * Verify Schnorr signature { r (v - xh mod q), e (g^v mod p) } against
250 * public exponent g_x (g^x) under group defined by 'grp_p', 'grp_q' and 251 * public exponent g_x (g^x) under group defined by 'grp_p', 'grp_q' and
251 * 'grp_g' using hash "evp_md". 252 * 'grp_g' using hash "hash_alg".
252 * Signature hash will be salted with 'idlen' bytes from 'id'. 253 * Signature hash will be salted with 'idlen' bytes from 'id'.
253 * Returns -1 on failure, 0 on incorrect signature or 1 on matching signature. 254 * Returns -1 on failure, 0 on incorrect signature or 1 on matching signature.
254 */ 255 */
255int 256int
256schnorr_verify(const BIGNUM *grp_p, const BIGNUM *grp_q, const BIGNUM *grp_g, 257schnorr_verify(const BIGNUM *grp_p, const BIGNUM *grp_q, const BIGNUM *grp_g,
257 const EVP_MD *evp_md, const BIGNUM *g_x, const u_char *id, u_int idlen, 258 int hash_alg, const BIGNUM *g_x, const u_char *id, u_int idlen,
258 const BIGNUM *r, const BIGNUM *e) 259 const BIGNUM *r, const BIGNUM *e)
259{ 260{
260 int success = -1; 261 int success = -1;
@@ -302,7 +303,7 @@ schnorr_verify(const BIGNUM *grp_p, const BIGNUM *grp_q, const BIGNUM *grp_g,
302 303
303 SCHNORR_DEBUG_BN((g_xh, "%s: g_xh = ", __func__)); 304 SCHNORR_DEBUG_BN((g_xh, "%s: g_xh = ", __func__));
304 /* h = H(g || g^v || g^x || id) */ 305 /* h = H(g || g^v || g^x || id) */
305 if ((h = schnorr_hash(grp_p, grp_q, grp_g, evp_md, e, g_x, 306 if ((h = schnorr_hash(grp_p, grp_q, grp_g, hash_alg, e, g_x,
306 id, idlen)) == NULL) { 307 id, idlen)) == NULL) {
307 error("%s: schnorr_hash failed", __func__); 308 error("%s: schnorr_hash failed", __func__);
308 goto out; 309 goto out;
@@ -385,7 +386,7 @@ schnorr_verify_buf(const BIGNUM *grp_p, const BIGNUM *grp_q,
385 goto out; 386 goto out;
386 } 387 }
387 388
388 ret = schnorr_verify(grp_p, grp_q, grp_g, EVP_sha256(), 389 ret = schnorr_verify(grp_p, grp_q, grp_g, SSH_DIGEST_SHA256,
389 g_x, id, idlen, r, e); 390 g_x, id, idlen, r, e);
390 out: 391 out:
391 BN_clear_free(e); 392 BN_clear_free(e);
@@ -443,43 +444,33 @@ bn_rand_range_gt_one(const BIGNUM *high)
443 return NULL; 444 return NULL;
444} 445}
445 446
447/* XXX convert all callers of this to use ssh_digest_memory() directly */
446/* 448/*
447 * Hash contents of buffer 'b' with hash 'md'. Returns 0 on success, 449 * Hash contents of buffer 'b' with hash 'md'. Returns 0 on success,
448 * with digest via 'digestp' (caller to free) and length via 'lenp'. 450 * with digest via 'digestp' (caller to free) and length via 'lenp'.
449 * Returns -1 on failure. 451 * Returns -1 on failure.
450 */ 452 */
451int 453int
452hash_buffer(const u_char *buf, u_int len, const EVP_MD *md, 454hash_buffer(const u_char *buf, u_int len, int hash_alg,
453 u_char **digestp, u_int *lenp) 455 u_char **digestp, u_int *lenp)
454{ 456{
455 u_char digest[EVP_MAX_MD_SIZE]; 457 u_char digest[SSH_DIGEST_MAX_LENGTH];
456 u_int digest_len; 458 u_int digest_len = ssh_digest_bytes(hash_alg);
457 EVP_MD_CTX evp_md_ctx;
458 int success = -1;
459 459
460 EVP_MD_CTX_init(&evp_md_ctx); 460 if (digest_len == 0) {
461 461 error("%s: invalid hash", __func__);
462 if (EVP_DigestInit_ex(&evp_md_ctx, md, NULL) != 1) { 462 return -1;
463 error("%s: EVP_DigestInit_ex", __func__);
464 goto out;
465 }
466 if (EVP_DigestUpdate(&evp_md_ctx, buf, len) != 1) {
467 error("%s: EVP_DigestUpdate", __func__);
468 goto out;
469 } 463 }
470 if (EVP_DigestFinal_ex(&evp_md_ctx, digest, &digest_len) != 1) { 464 if (ssh_digest_memory(hash_alg, buf, len, digest, digest_len) != 0) {
471 error("%s: EVP_DigestFinal_ex", __func__); 465 error("%s: digest_memory failed", __func__);
472 goto out; 466 return -1;
473 } 467 }
474 *digestp = xmalloc(digest_len); 468 *digestp = xmalloc(digest_len);
475 *lenp = digest_len; 469 *lenp = digest_len;
476 memcpy(*digestp, digest, *lenp); 470 memcpy(*digestp, digest, *lenp);
477 success = 0;
478 out:
479 EVP_MD_CTX_cleanup(&evp_md_ctx);
480 bzero(digest, sizeof(digest)); 471 bzero(digest, sizeof(digest));
481 digest_len = 0; 472 digest_len = 0;
482 return success; 473 return 0;
483} 474}
484 475
485/* print formatted string followed by bignum */ 476/* print formatted string followed by bignum */