Commit 007bb64e authored by Niels Möller's avatar Niels Möller

*** empty log message ***

Rev: src/.cvsignore:1.21
Rev: src/rsa.c:1.4
Rev: src/rsa.h:1.1
Rev: src/rsa_keygen.c:1.1
parent b5e8fb18
......@@ -20,9 +20,9 @@ digit_table
digit_table.h
lsh
lsh-decode-key
lsh_keygen
lsh-keygen
lsh-writekey
lsh_proxy
lsh_writekey
lshd
packet_types.h
pkcs5-test
......
......@@ -20,9 +20,9 @@
/digit_table.h
/lsh
/lsh-decode-key
/lsh_keygen
/lsh-keygen
/lsh-writekey
/lsh_proxy
/lsh_writekey
/lshd
/packet_types.h
/pkcs5-test
......
......@@ -22,24 +22,26 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "publickey_crypto.h"
#include "rsa.h"
#include "atoms.h"
#include "bignum.h"
#include "crypto.h"
#include "format.h"
#include "parse.h"
#include "sexp.h"
#include "sha.h"
#include "ssh.h"
/* #include "ssh.h" */
#include "werror.h"
#include "xalloc.h"
#include <assert.h>
#define GABA_DEFINE
#include "rsa.h.x"
#undef GABA_DEFINE
#include "rsa.c.x"
/* GABA:
/* ;; GABA:
(class
(name rsa_algorithm)
(super signature_algorithm)
......@@ -54,11 +56,11 @@
*/
static void
pkcs_1_encode(mpz_t m,
struct rsa_algorithm *params,
UINT32 length,
UINT32 msg_length,
const UINT8 *msg)
pkcs1_encode(mpz_t m,
struct rsa_algorithm *params,
UINT32 length,
UINT32 msg_length,
const UINT8 *msg)
{
UINT8 *em = alloca(length);
unsigned i = length;
......@@ -124,8 +126,8 @@ static int
spki_init_rsa_public(struct rsa_public *key,
struct sexp_iterator *i)
{
return (sexp_get_un(i, ATOM_N, key->n)
&& sexp_get_un(i, ATOM_E, key->e)
return (sexp_get_un(i, ATOM_N, key->n, RSA_MAX_SIZE)
&& sexp_get_un(i, ATOM_E, key->e, RSA_MAX_SIZE)
&& rsa_check_size(key));
}
......@@ -166,7 +168,7 @@ spki_init_rsa_public(struct rsa_public *key,
/* Compute x, the d:th root of m. Calling it with x == m is allowed. */
static void
compute_rsa_root(struct rsa_signer *self, mpz_t x, mpz_t m)
rsa_compute_root(struct rsa_signer *self, mpz_t x, mpz_t m)
{
#if RSA_CRT
mpz_t xp; /* modulo p */
......@@ -237,12 +239,18 @@ do_rsa_sign(struct signer *s,
mpz_t m;
mpz_init(m);
pkcs_1_encode(m, self->public.params, self->public.size - 1,
msg_length, msg);
pkcs1_encode(m, self->public.params, self->public.size - 1,
msg_length, msg);
rsa_compute_root(self, m, m);
compute_rsa_root(self, m, m);
/* Uses the encoding:
*
* string rsa-pkcs1
* string signature-blob
*/
res = ssh_format("%lun", m);
res = ssh_format("%a%un", m);
mpz_clear(m);
return res;
......@@ -254,8 +262,22 @@ do_rsa_sign_spki(struct signer *s,
UINT32 msg_length,
const UINT8 *msg)
{
fatal("do_rsa_sign_spki() not implemented.\n");
CAST(rsa_signer, self, s);
mpz_t m;
struct sexp *signature;
mpz_init(m);
pkcs1_encode(m, self->public.params, self->public.size - 1,
msg_length, msg);
rsa_compute_root(self, m, m);
/* Build signature */
signature = sexp_l(4, sexp_a(ATOM_SIGNATURE), hash, principal,
sexp_un(m), -1);
mpz_clear(m);
return signature;
}
static struct sexp *
......@@ -264,12 +286,39 @@ do_rsa_public_key(struct signer *s)
CAST(rsa_signer, self, s);
return sexp_l(2, sexp_a(ATOM_PUBLIC_KEY),
sexp_l(3, sexp_a(ATOM_RSA_PKCS1),
sexp_l(3, sexp_a(ATOM_RSA_PKCS1_SHA1),
sexp_l(2, sexp_a(ATOM_N), sexp_un(self->public.n), -1),
sexp_l(2, sexp_a(ATOM_E), sexp_un(self->public.e), -1),
-1), -1);
}
static int
rsa_pkcs1_verify(struct rsa_verifier *self,
UINT32 length,
const UINT8 *msg,
mpz_t signature)
{
int res;
mpz_t m;
mpz_t s;
if (mpz_cmp(signature, self->public.n) >= 0)
return 0;
mpz_init(m);
mpz_init(s);
mpz_powm(s, signature, self->public.e, self->public.n);
pkcs1_encode(m, self->public.params, self->public.size - 1,
length, msg);
res = !mpz_cmp(m, s);
mpz_clear(m); mpz_clear(s);
return res;
}
static int
do_rsa_verify(struct verifier *v,
UINT32 length,
......@@ -278,41 +327,43 @@ do_rsa_verify(struct verifier *v,
const UINT8 *signature_data)
{
CAST(rsa_verifier, self, v);
mpz_t m;
mpz_t s;
int res;
if (signature_length > self->public.size)
return 0;
mpz_init(s);
bignum_parse_u(s, signature_length, signature_data);
if (mpz_cmp(s, self->public.n) >= 0)
{
mpz_clear(s);
return 0;
}
mpz_powm(s, s, self->public.e, self->public.n);
mpz_init(m);
pkcs_1_encode(m, self->public.params, self->public.size - 1,
length, msg);
res = rsa_pkcs1_verify(self, length, msg, s);
mpz_clear(s);
res = !mpz_cmp(m, s);
mpz_clear(m); mpz_clear(s);
return res;
}
static int
do_rsa_verify_spki(struct verifier *s,
do_rsa_verify_spki(struct verifier *v,
UINT32 length,
const UINT8 *msg,
struct sexp_iterator *i)
{
fatal("do_rsa_verify_spki() not implemented.\n");
CAST(rsa_verifier, self, v);
mpz_t s;
int res;
if (SEXP_LEFT(i) != 1)
return 0;
mpz_init(s);
res = (sexp2bignum_u(SEXP_GET(i), s, self->public.size)
&& rsa_pkcs1_verify(self, length, msg, s));
mpz_clear(s);
return res;
}
static struct signer *
......@@ -323,9 +374,14 @@ make_rsa_signer(struct signature_algorithm *s,
NEW(rsa_signer, res);
init_rsa_public(&res->public, params);
if ( (SEXP_LEFT(i) >= 3)
if ( (SEXP_LEFT(i) == 8)
&& spki_init_rsa_public(&res->public, i)
&& sexp_get_un(i, ATOM_D, res->d) )
&& sexp_get_un(i, ATOM_D, res->d, RSA_MAX_SIZE)
&& sexp_get_un(i, ATOM_P, res->p, RSA_MAX_SIZE)
&& sexp_get_un(i, ATOM_Q, res->q, RSA_MAX_SIZE)
&& sexp_get_un(i, ATOM_A, res->a, RSA_MAX_SIZE)
&& sexp_get_un(i, ATOM_B, res->b, RSA_MAX_SIZE)
&& sexp_get_un(i, ATOM_C, res->c, RSA_MAX_SIZE) )
{
res->super.sign = do_rsa_sign;
res->super.sign_spki = do_rsa_sign_spki;
......
/* rsa.h
*
* $Id$
*/
/* lsh, an implementation of the ssh protocol
*
* Copyright (C) 2000 Niels Mller
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef LSH_RSA_H_INCLUDED
#define LSH_RSA_H_INCLUDED
#include "bignum.h"
#include "publickey_crypto.h"
#define GABA_DECLARE
#include "rsa.h.x"
#undef GABA_DECLARE
/* We don't allow keys larger than 5000 bits (i.e. 625 octets). Note
* that allowing really large keys opens for Denial-of-service
* attacks. */
#define RSA_MAX_SIZE 625
/* GABA:
(class
(name rsa_algorithm)
(super signature_algorithm)
(vars
(hash object hash_algorithm)
; The complete prefix for a DigestInfo, including the algorithm
; identifier for the hash function. A DigestInfo is formed by
; cetenating this prefix with the raw hash value.
(prefix_length . UINT32)
(prefix . "const UINT8 *")))
*/
struct signature_algorithm *
make_rsa_algorithm(struct hash_algorithm *hash,
UINT32 prefix_length,
const UINT8 *prefix);
extern struct rsa_algorithm rsa_md5_algorithm;
extern struct rsa_algorithm rsa_sha1_algorithm;
struct sexp *
rsa_generate_key(mpz_t e, struct randomness *r, UINT32 bits);
#endif /* LSH_RSA_H_INCLUDED */
/* rsa_keygen.c
*
* Generate rsa key pairs..
*
* $Id$
*/
/* lsh, an implementation of the ssh protocol
*
* Copyright (C) 2000 Niels Mller
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "rsa.h"
#include "sexp.h"
#include "werror.h"
#define SA(x) sexp_a(ATOM_##x)
/* Takes the public exponent e as argument. */
struct sexp *
rsa_generate_key(mpz_t e, struct randomness *r, UINT32 bits)
{
struct sexp *key = NULL;
mpz_t n;
mpz_t d;
mpz_t p; mpz_t q;
mpz_t a; mpz_t b; mpz_t c;
mpz_t phi;
mpz_t tmp;
mpz_init(n); mpz_init(d); mpz_init(p), mpz_init(q);
mpz_init(a); mpz_init(b); mpz_init(c);
mpz_init(phi); mpz_init(tmp);
/* Generate primes */
bignum_random_prime(p, r, bits/2);
bignum_random_prime(q, r, (bits+1)/2);
debug("p = %xn\nq = %xn\n", p, q);
/* Compute modulo */
mpz_mul(n, p, q);
debug("n = %xn\n", n);
/* Compute phi, as well as d % p and d % q */
mpz_sub_ui(phi, p, 1);
mpz_fdiv_r(a, d, phi);
mpz_sub_ui(tmp, q, 1);
mpz_fdiv_r(b, d, tmp);
mpz_mul(phi, phi, tmp);
debug("phi = %xn\ne = %xn\n", phi, e);
/* Compute d such that e d = 1 (mod phi) */
/* NOTE: mpz_invert sometimes generates negative inverses. */
if (!mpz_invert(d, e, phi))
{
werror("rsa_generate_key: e not invertible.");
goto done;
}
if (mpz_sgn(d) < 0)
mpz_fdiv_r(d, d, phi);
debug("d = %xn\n", d);
/* Compute inverse of q, also needed for the CRT optimization */
if (!mpz_invert(c, q, p))
{
werror("rsa_generate_key: q not invertible.");
goto done;
}
if (mpz_sgn(c) < 0)
mpz_fdiv_r(c, c, p);
debug("a = %xn\n b = %xn\nc=%xn\n", a, b, c);
/* FIXME: Add sanity checking */
key = sexp_l(2, SA(PRIVATE_KEY),
sexp_l(9, SA(RSA_PKCS1_SHA1),
sexp_l(2, SA(N), sexp_un(n), -1),
sexp_l(2, SA(E), sexp_un(e), -1),
sexp_l(2, SA(D), sexp_un(d), -1),
sexp_l(2, SA(P), sexp_un(p), -1),
sexp_l(2, SA(Q), sexp_un(q), -1),
sexp_l(2, SA(A), sexp_un(a), -1),
sexp_l(2, SA(B), sexp_un(b), -1),
sexp_l(2, SA(C), sexp_un(c), -1), -1), -1);
done:
mpz_clear(n); mpz_clear(d); mpz_clear(p), mpz_clear(q);
mpz_clear(a); mpz_clear(b); mpz_clear(c);
mpz_clear(phi); mpz_clear(tmp);
return key;
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment