Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
LSH
lsh
Commits
69b36b2c
Commit
69b36b2c
authored
Jun 14, 1999
by
Niels Möller
Browse files
* src/publickey_crypto.c: Moved the dsa-ralated code to a separate
file. Rev: src/publickey_crypto.c:1.33
parent
5e6da035
Changes
1
Hide whitespace changes
Inline
Side-by-side
src/publickey_crypto.c
View file @
69b36b2c
...
...
@@ -30,7 +30,6 @@
#include
"crypto.h"
#include
"format.h"
#include
"parse.h"
#include
"publickey_crypto.h"
#include
"sha.h"
#include
"ssh.h"
#include
"werror.h"
...
...
@@ -44,377 +43,6 @@
#include
"publickey_crypto.c.x"
/* DSA signatures */
/* GABA:
(class
(name dsa_signer)
(super signer)
(vars
(random object randomness)
(public struct dsa_public)
(a bignum)))
*/
/* GABA:
(class
(name dsa_signer_kludge)
(super signer)
(vars
(dsa object dsa_signer)))
*/
/* GABA:
(class
(name dsa_verifier)
(super verifier)
(vars
(public struct dsa_public)))
*/
/* GABA:
(class
(name dsa_algorithm)
(super signature_algorithm)
(vars
(random object randomness)))
*/
static
void
dsa_hash
(
mpz_t
h
,
UINT32
length
,
UINT8
*
msg
)
{
/* Compute hash */
struct
hash_instance
*
hash
=
MAKE_HASH
(
&
sha_algorithm
);
UINT8
*
digest
=
alloca
(
hash
->
hash_size
);
HASH_UPDATE
(
hash
,
length
,
msg
);
HASH_DIGEST
(
hash
,
digest
);
bignum_parse_u
(
h
,
hash
->
hash_size
,
digest
);
debug
(
"DSA hash: %xn
\n
"
,
h
);
KILL
(
hash
);
}
static
void
generic_dsa_sign
(
struct
dsa_signer
*
closure
,
UINT32
length
,
UINT8
*
msg
,
mpz_t
r
,
mpz_t
s
)
{
mpz_t
k
,
tmp
;
assert
(
r
&&
s
);
/* Select k, 0<k<q, randomly */
mpz_init_set
(
tmp
,
closure
->
public
.
q
);
mpz_sub_ui
(
tmp
,
tmp
,
1
);
mpz_init
(
k
);
bignum_random
(
k
,
closure
->
random
,
tmp
);
mpz_add_ui
(
k
,
k
,
1
);
debug
(
"generic_dsa_sign, k: %xn
\n
"
,
k
);
/* Compute r = (g^k (mod p)) (mod q) */
mpz_powm
(
r
,
closure
->
public
.
g
,
k
,
closure
->
public
.
p
);
debug
(
"do_dsa_sign, group element: %xn
\n
"
,
r
);
mpz_fdiv_r
(
r
,
r
,
closure
->
public
.
q
);
debug
(
"do_dsa_sign, r: %xn
\n
"
,
r
);
/* Compute hash */
dsa_hash
(
tmp
,
length
,
msg
);
/* Compute k^-1 (mod q) */
if
(
!
mpz_invert
(
k
,
k
,
closure
->
public
.
q
))
{
fatal
(
"do_dsa_sign: k non-invertible
\n
"
);
}
/* Compute signature s = k^-1(h + ar) (mod q) */
mpz_mul
(
s
,
r
,
closure
->
a
);
mpz_fdiv_r
(
s
,
s
,
closure
->
public
.
q
);
mpz_add
(
s
,
s
,
tmp
);
mpz_mul
(
s
,
s
,
k
);
mpz_fdiv_r
(
s
,
s
,
closure
->
public
.
q
);
debug
(
"generic_dsa_sign, s: %xn
\n
"
,
s
);
mpz_clear
(
k
);
mpz_clear
(
tmp
);
}
static
struct
lsh_string
*
do_dsa_sign
(
struct
signer
*
c
,
UINT32
length
,
UINT8
*
msg
)
{
CAST
(
dsa_signer
,
closure
,
c
);
mpz_t
r
,
s
;
struct
lsh_string
*
signature
;
mpz_init
(
r
);
mpz_init
(
s
);
generic_dsa_sign
(
closure
,
length
,
msg
,
r
,
s
);
/* Build signature */
/* FIXME: Uses the (better) format from an obsoleted draft */
signature
=
ssh_format
(
"%a%n%n"
,
ATOM_SSH_DSS
,
r
,
s
);
mpz_clear
(
r
);
mpz_clear
(
s
);
return
signature
;
}
#if DATAFELLOWS_SSH2_SSH_DSA_KLUDGE
static
struct
lsh_string
*
do_dsa_sign_kludge
(
struct
signer
*
c
,
UINT32
length
,
UINT8
*
msg
)
{
CAST
(
dsa_signer_kludge
,
self
,
c
);
mpz_t
r
,
s
;
struct
lsh_string
*
signature
;
mpz_init
(
r
);
mpz_init
(
s
);
generic_dsa_sign
(
self
->
dsa
,
length
,
msg
,
r
,
s
);
/* Build signature */
/* FIXME: This generates length fields, and it also doesn't
* guarantee that r and s occupy half of the signature each. */
signature
=
ssh_format
(
"%un%un"
,
r
,
s
);
mpz_clear
(
r
);
mpz_clear
(
s
);
return
signature
;
}
#endif
/* DATAFELLOWS_SSH2_SSH_DSA_KLUDGE */
#if 0
static struct lsh_string *dsa_public_key(struct signer *dsa)
{
return ssh_format("%a%n%n%n%n",
ATOM_SSH_DSS, dsa->p, dsa->q, dsa->g, dsa->y);
}
#endif
static
int
do_dsa_verify
(
struct
verifier
*
c
,
UINT32
length
,
UINT8
*
msg
,
UINT32
signature_length
,
UINT8
*
signature_data
)
{
CAST
(
dsa_verifier
,
closure
,
c
);
struct
simple_buffer
buffer
;
int
res
;
int
atom
;
mpz_t
r
,
s
;
mpz_t
w
,
tmp
,
v
;
simple_buffer_init
(
&
buffer
,
signature_length
,
signature_data
);
if
(
!
parse_atom
(
&
buffer
,
&
atom
)
||
(
atom
!=
ATOM_SSH_DSS
)
)
return
0
;
mpz_init
(
r
);
mpz_init
(
s
);
if
(
!
(
parse_bignum
(
&
buffer
,
r
)
&&
parse_bignum
(
&
buffer
,
s
)
&&
parse_eod
(
&
buffer
)
&&
(
mpz_sgn
(
r
)
==
1
)
&&
(
mpz_sgn
(
s
)
==
1
)
&&
(
mpz_cmp
(
r
,
closure
->
public
.
q
)
<
0
)
&&
(
mpz_cmp
(
s
,
closure
->
public
.
q
)
<
0
)
))
{
mpz_clear
(
r
);
mpz_clear
(
s
);
return
0
;
}
debug
(
"do_dsa_verify, r: %xn
\n
"
" s: %xn
\n
"
,
r
,
s
);
/* Compute w = s^-1 (mod q) */
mpz_init
(
w
);
/* FIXME: mpz_invert generates negative inverses. Is this a problem? */
if
(
!
mpz_invert
(
w
,
s
,
closure
->
public
.
q
))
{
werror
(
"do_dsa_verify: s non-invertible.
\n
"
);
mpz_clear
(
r
);
mpz_clear
(
s
);
mpz_clear
(
w
);
return
0
;
}
debug
(
"do_dsa_verify, w: %xn
\n
"
,
w
);
/* Compute hash */
mpz_init
(
tmp
);
dsa_hash
(
tmp
,
length
,
msg
);
/* g^{w * h (mod q)} (mod p) */
mpz_init
(
v
);
mpz_mul
(
tmp
,
tmp
,
w
);
mpz_fdiv_r
(
tmp
,
tmp
,
closure
->
public
.
q
);
debug
(
"u1: %xn
\n
"
,
tmp
);
mpz_powm
(
v
,
closure
->
public
.
g
,
tmp
,
closure
->
public
.
p
);
/* y^{w * r (mod q) } (mod p) */
mpz_mul
(
tmp
,
r
,
w
);
mpz_fdiv_r
(
tmp
,
tmp
,
closure
->
public
.
q
);
debug
(
"u2: %xn
\n
"
,
tmp
);
mpz_powm
(
tmp
,
closure
->
public
.
y
,
tmp
,
closure
->
public
.
p
);
/* (g^{w * h} * y^{w * r} (mod p) ) (mod q) */
mpz_mul
(
v
,
v
,
tmp
);
mpz_fdiv_r
(
v
,
v
,
closure
->
public
.
p
);
debug
(
"do_dsa_verify, group element: %xn
\n
"
,
v
);
mpz_fdiv_r
(
v
,
v
,
closure
->
public
.
q
);
debug
(
"do_dsa_verify, v: %xn
\n
"
,
v
);
res
=
mpz_cmp
(
v
,
r
);
mpz_clear
(
r
);
mpz_clear
(
s
);
mpz_clear
(
w
);
mpz_clear
(
tmp
);
mpz_clear
(
v
);
return
!
res
;
}
static
int
parse_dsa_public
(
struct
simple_buffer
*
buffer
,
struct
dsa_public
*
public
)
{
return
(
parse_bignum
(
buffer
,
public
->
p
)
&&
(
mpz_sgn
(
public
->
p
)
==
1
)
&&
parse_bignum
(
buffer
,
public
->
q
)
&&
(
mpz_sgn
(
public
->
q
)
==
1
)
&&
(
mpz_cmp
(
public
->
q
,
public
->
p
)
<
0
)
/* q < p */
&&
parse_bignum
(
buffer
,
public
->
g
)
&&
(
mpz_sgn
(
public
->
g
)
==
1
)
&&
(
mpz_cmp
(
public
->
g
,
public
->
p
)
<
0
)
/* g < p */
&&
parse_bignum
(
buffer
,
public
->
y
)
&&
(
mpz_sgn
(
public
->
y
)
==
1
)
&&
(
mpz_cmp
(
public
->
y
,
public
->
p
)
<
0
)
/* y < p */
);
}
/* FIXME: Outside of the protocol transactions, keys should be stored
* in SPKI-style S-expressions. */
static
struct
signer
*
make_dsa_signer
(
struct
signature_algorithm
*
c
,
UINT32
public_length
,
UINT8
*
public
,
UINT32
private_length
,
UINT8
*
private
)
{
CAST
(
dsa_algorithm
,
closure
,
c
);
NEW
(
dsa_signer
,
res
);
struct
simple_buffer
public_buffer
;
struct
simple_buffer
private_buffer
;
int
atom
;
/* FIXME: The allocator could do this kind of initialization
* automatically. */
mpz_init
(
res
->
public
.
p
);
mpz_init
(
res
->
public
.
q
);
mpz_init
(
res
->
public
.
g
);
mpz_init
(
res
->
public
.
y
);
mpz_init
(
res
->
a
);
simple_buffer_init
(
&
public_buffer
,
public_length
,
public
);
if
(
!
parse_atom
(
&
public_buffer
,
&
atom
)
||
(
atom
!=
ATOM_SSH_DSS
)
)
{
KILL
(
res
);
return
0
;
}
simple_buffer_init
(
&
private_buffer
,
private_length
,
private
);
if
(
!
(
parse_dsa_public
(
&
public_buffer
,
&
res
->
public
)
&&
parse_bignum
(
&
private_buffer
,
res
->
a
)
/* FIXME: Perhaps do some more sanity checks? */
&&
(
mpz_sgn
(
res
->
a
)
==
1
)
&&
parse_eod
(
&
private_buffer
)
))
{
KILL
(
res
);
return
NULL
;
}
res
->
super
.
sign
=
do_dsa_sign
;
res
->
random
=
closure
->
random
;
return
&
res
->
super
;
}
#if DATAFELLOWS_SSH2_SSH_DSA_KLUDGE
struct
signer
*
make_dsa_signer_kludge
(
struct
signer
*
s
)
{
NEW
(
dsa_signer_kludge
,
self
);
CAST
(
dsa_signer
,
dsa
,
s
);
self
->
super
.
sign
=
do_dsa_sign_kludge
;
self
->
dsa
=
dsa
;
return
&
self
->
super
;
}
#endif
/* DATAFELLOWS_SSH2_SSH_DSA_KLUDGE */
static
struct
verifier
*
make_dsa_verifier
(
struct
signature_algorithm
*
closure
UNUSED
,
UINT32
public_length
,
UINT8
*
public
)
{
NEW
(
dsa_verifier
,
res
);
struct
simple_buffer
buffer
;
int
atom
;
/* FIXME: The allocator could do this kind of initialization
* automatically. */
mpz_init
(
res
->
public
.
p
);
mpz_init
(
res
->
public
.
q
);
mpz_init
(
res
->
public
.
g
);
mpz_init
(
res
->
public
.
y
);
simple_buffer_init
(
&
buffer
,
public_length
,
public
);
if
(
!
parse_atom
(
&
buffer
,
&
atom
)
||
(
atom
!=
ATOM_SSH_DSS
)
)
{
KILL
(
res
);
return
0
;
}
if
(
!
parse_dsa_public
(
&
buffer
,
&
res
->
public
))
/* FIXME: Perhaps do some more sanity checks? */
{
KILL
(
res
);
return
NULL
;
}
res
->
super
.
verify
=
do_dsa_verify
;
return
&
res
->
super
;
}
struct
signature_algorithm
*
make_dsa_algorithm
(
struct
randomness
*
random
)
{
NEW
(
dsa_algorithm
,
dsa
);
dsa
->
super
.
make_signer
=
make_dsa_signer
;
dsa
->
super
.
make_verifier
=
make_dsa_verifier
;
dsa
->
random
=
random
;
return
&
dsa
->
super
;
}
/* Groups */
/* GABA:
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment