summaryrefslogtreecommitdiffstats
path: root/crypto/openssh/schnorr.c
diff options
context:
space:
mode:
Diffstat (limited to 'crypto/openssh/schnorr.c')
-rw-r--r--crypto/openssh/schnorr.c38
1 files changed, 32 insertions, 6 deletions
diff --git a/crypto/openssh/schnorr.c b/crypto/openssh/schnorr.c
index daeec06..fb6bd5e 100644
--- a/crypto/openssh/schnorr.c
+++ b/crypto/openssh/schnorr.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: schnorr.c,v 1.3 2009/03/05 07:18:19 djm Exp $ */
+/* $OpenBSD: schnorr.c,v 1.5 2010/12/03 23:49:26 djm Exp $ */
/* $FreeBSD$ */
/*
* Copyright (c) 2008 Damien Miller. All rights reserved.
@@ -141,6 +141,10 @@ schnorr_sign(const BIGNUM *grp_p, const BIGNUM *grp_q, const BIGNUM *grp_g,
error("%s: g_x < 1", __func__);
return -1;
}
+ if (BN_cmp(g_x, grp_p) >= 0) {
+ error("%s: g_x > g", __func__);
+ return -1;
+ }
h = g_v = r = tmp = v = NULL;
if ((bn_ctx = BN_CTX_new()) == NULL) {
@@ -257,14 +261,19 @@ schnorr_verify(const BIGNUM *grp_p, const BIGNUM *grp_q, const BIGNUM *grp_g,
const BIGNUM *r, const BIGNUM *e)
{
int success = -1;
- BIGNUM *h, *g_xh, *g_r, *expected;
+ BIGNUM *h = NULL, *g_xh = NULL, *g_r = NULL, *gx_q = NULL;
+ BIGNUM *expected = NULL;
BN_CTX *bn_ctx;
SCHNORR_DEBUG_BN((g_x, "%s: g_x = ", __func__));
/* Avoid degenerate cases: g^0 yields a spoofable signature */
if (BN_cmp(g_x, BN_value_one()) <= 0) {
- error("%s: g_x < 1", __func__);
+ error("%s: g_x <= 1", __func__);
+ return -1;
+ }
+ if (BN_cmp(g_x, grp_p) >= 0) {
+ error("%s: g_x >= p", __func__);
return -1;
}
@@ -275,6 +284,7 @@ schnorr_verify(const BIGNUM *grp_p, const BIGNUM *grp_q, const BIGNUM *grp_g,
}
if ((g_xh = BN_new()) == NULL ||
(g_r = BN_new()) == NULL ||
+ (gx_q = BN_new()) == NULL ||
(expected = BN_new()) == NULL) {
error("%s: BN_new", __func__);
goto out;
@@ -283,6 +293,17 @@ schnorr_verify(const BIGNUM *grp_p, const BIGNUM *grp_q, const BIGNUM *grp_g,
SCHNORR_DEBUG_BN((e, "%s: e = ", __func__));
SCHNORR_DEBUG_BN((r, "%s: r = ", __func__));
+ /* gx_q = (g^x)^q must === 1 mod p */
+ if (BN_mod_exp(gx_q, g_x, grp_q, grp_p, bn_ctx) == -1) {
+ error("%s: BN_mod_exp (g_x^q mod p)", __func__);
+ goto out;
+ }
+ if (BN_cmp(gx_q, BN_value_one()) != 0) {
+ error("%s: Invalid signature (g^x)^q != 1 mod p", __func__);
+ goto out;
+ }
+
+ SCHNORR_DEBUG_BN((g_xh, "%s: g_xh = ", __func__));
/* h = H(g || g^v || g^x || id) */
if ((h = schnorr_hash(grp_p, grp_q, grp_g, evp_md, e, g_x,
id, idlen)) == NULL) {
@@ -317,9 +338,14 @@ schnorr_verify(const BIGNUM *grp_p, const BIGNUM *grp_q, const BIGNUM *grp_g,
BN_CTX_free(bn_ctx);
if (h != NULL)
BN_clear_free(h);
- BN_clear_free(g_xh);
- BN_clear_free(g_r);
- BN_clear_free(expected);
+ if (gx_q != NULL)
+ BN_clear_free(gx_q);
+ if (g_xh != NULL)
+ BN_clear_free(g_xh);
+ if (g_r != NULL)
+ BN_clear_free(g_r);
+ if (expected != NULL)
+ BN_clear_free(expected);
return success;
}
OpenPOWER on IntegriCloud