source: trunk/third/ssh/rsaglue.c @ 12646

Revision 12646, 7.2 KB checked in by danw, 26 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r12645, which included commits to RCS files with non-trunk default branches.
Line 
1/*
2
3rsaglue.c
4
5Author: Tatu Ylonen <ylo@cs.hut.fi>
6
7Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
8                   All rights reserved
9
10Created: Tue Apr 11 15:17:50 1995 ylo
11
12Glue code to be able to do RSA encryption/decryption with RSAREF.  The purpose
13of this file is to permit compiling this software with RSAREF.  Using RSAREF
14may make this software legal for noncommercial use without licencing the
15RSA patents.  RSAREF code is only used if the system is configured
16using the --with-rsaref configure option.
17
18*/
19
20/*
21 * $Id: rsaglue.c,v 1.1.1.2 1999-03-08 17:43:18 danw Exp $
22 * $Log: not supported by cvs2svn $
23 * Revision 1.5  1997/03/19  21:29:59  kivinen
24 *      Added missing &.
25 *
26 * Revision 1.4  1997/03/19 21:14:08  kivinen
27 *      Added checks that public key exponent cannot be less than 3.
28 *
29 * Revision 1.3  1996/07/31 07:02:32  huima
30 * *** empty log message ***
31 *
32 * Revision 1.2  1996/07/07 12:48:14  ylo
33 *      A fixed size buffer was used to store decrypted value without
34 *      checking bounds, which could cause stack to be overwritten
35 *      with very large keys.  Changed to use xmallocated buffer.
36 *
37 * Revision 1.1.1.1  1996/02/18 21:38:12  ylo
38 *      Imported ssh-1.2.13.
39 *
40 * Revision 1.4  1995/07/26  23:29:34  ylo
41 *      Display a fatal error if key size > 1024 with RSAREF.
42 *
43 * Revision 1.3  1995/07/26  17:08:59  ylo
44 *      Changed to use new functions in mpaux.c for
45 *      linearizing/unlinearizing mp-ints.
46 *
47 * Revision 1.2  1995/07/13  01:33:27  ylo
48 *      Removed "Last modified" header.
49 *      Added cvs log.
50 *
51 * $Endlog$
52 */
53
54#include "includes.h"
55#include <gmp.h>
56#include "ssh.h"
57#include "rsa.h"
58#include "getput.h"
59#include "mpaux.h"
60#include "xmalloc.h"
61
62#ifdef RSAREF
63
64/* This code uses the following RSAREF functions:
65     RSAPublicEncrypt
66     RSAPrivateDecrypt
67     R_RandomInit
68     R_RandomUpdate
69     R_RandomFinal
70   These functions are exported by RSAREF and are thus part of the available
71   interface without modifying RSAREF. */
72
73#define _MD5_H_ /* Kludge to prevent inclusion of rsaref md5.h. */
74#include "rsaref2/source/global.h"
75#include "rsaref2/source/rsaref.h"
76
77/* Convert an integer from gmp to rsaref representation. */
78
79void gmp_to_rsaref(unsigned char *buf, unsigned int len, MP_INT *value)
80{
81  mp_linearize_msb_first(buf, len, value);
82}
83
84/* Convert an integer from rsaref to gmp representation. */
85
86void rsaref_to_gmp(MP_INT *value, const unsigned char *buf, unsigned int len)
87{
88  mp_unlinearize_msb_first(value, buf, len);
89}
90
91/* Convert a public key from our representation to rsaref representation. */
92
93void rsaref_public_key(R_RSA_PUBLIC_KEY *rsa, RSAPublicKey *key)
94{
95  rsa->bits = key->bits;
96  gmp_to_rsaref(rsa->modulus, MAX_RSA_MODULUS_LEN, &key->n);
97  gmp_to_rsaref(rsa->exponent, MAX_RSA_MODULUS_LEN, &key->e);
98}
99
100/* Convert a private key from our representation to rsaref representation.
101   Note that some fo the constants are computed a little dfifferently
102   in rsaref. */
103
104void rsaref_private_key(R_RSA_PRIVATE_KEY *rsa, RSAPrivateKey *key)
105{
106  MP_INT aux;
107  rsa->bits = key->bits;
108  gmp_to_rsaref(rsa->modulus, MAX_RSA_MODULUS_LEN, &key->n);
109  gmp_to_rsaref(rsa->publicExponent, MAX_RSA_MODULUS_LEN, &key->e);
110  gmp_to_rsaref(rsa->exponent, MAX_RSA_MODULUS_LEN, &key->d);
111  gmp_to_rsaref(rsa->prime[0], MAX_RSA_PRIME_LEN, &key->q);
112  gmp_to_rsaref(rsa->prime[1], MAX_RSA_PRIME_LEN, &key->p);
113  mpz_init_set(&aux, &key->q);
114  mpz_sub_ui(&aux, &aux, 1);
115  mpz_mod(&aux, &key->d, &aux);
116  gmp_to_rsaref(rsa->primeExponent[0], MAX_RSA_PRIME_LEN, &aux);
117  mpz_set(&aux, &key->p);
118  mpz_sub_ui(&aux, &aux, 1);
119  mpz_mod(&aux, &key->d, &aux);
120  gmp_to_rsaref(rsa->primeExponent[1], MAX_RSA_PRIME_LEN, &aux);
121  gmp_to_rsaref(rsa->coefficient, MAX_RSA_PRIME_LEN, &key->u);
122}
123
124/* Performs a public key encrypt operation. */
125
126void rsa_public_encrypt(MP_INT *output, MP_INT *input, RSAPublicKey *key,
127                        RandomState *random_state)
128{
129  unsigned char input_data[MAX_RSA_MODULUS_LEN];
130  unsigned char output_data[MAX_RSA_MODULUS_LEN];
131  unsigned char buf[256];
132  unsigned int input_len, output_len, i, input_bits;
133  R_RSA_PUBLIC_KEY public_key;
134  R_RANDOM_STRUCT rands;
135
136  if (key->bits > MAX_RSA_MODULUS_BITS)
137    fatal("RSA key has too many bits for RSAREF to handle (max %d).",
138          MAX_RSA_MODULUS_BITS);
139
140  input_bits = mpz_sizeinbase(input, 2);
141  input_len = (input_bits + 7) / 8;
142  gmp_to_rsaref(input_data, input_len, input);
143
144  rsaref_public_key(&public_key, key);
145
146  R_RandomInit(&rands);
147  for (i = 0; i < 256; i++)
148    buf[i] = random_get_byte(random_state);
149  R_RandomUpdate(&rands, buf, 256);
150
151  if (RSAPublicEncrypt(output_data, &output_len, input_data, input_len,
152                       &public_key, &rands) != 0)
153    fatal("RSAPublicEncrypt failed");
154
155  R_RandomFinal(&rands);
156
157  rsaref_to_gmp(output, output_data, output_len);
158}
159
160/* Performs a private key decrypt operation. */
161
162void rsa_private_decrypt(MP_INT *output, MP_INT *input, RSAPrivateKey *key)
163{
164  unsigned char input_data[MAX_RSA_MODULUS_LEN];
165  unsigned char output_data[MAX_RSA_MODULUS_LEN];
166  unsigned int input_len, output_len, input_bits;
167  R_RSA_PRIVATE_KEY private_key;
168
169  if (key->bits > MAX_RSA_MODULUS_BITS)
170    fatal("RSA key has too many bits for RSAREF to handle (max %d).",
171          MAX_RSA_MODULUS_BITS);
172 
173  input_bits = mpz_sizeinbase(input, 2);
174  input_len = (input_bits + 7) / 8;
175  gmp_to_rsaref(input_data, input_len, input);
176
177  rsaref_private_key(&private_key, key);
178
179  if (RSAPrivateDecrypt(output_data, &output_len, input_data, input_len,
180                        &private_key) != 0)
181    fatal("RSAPrivateDecrypt failed");
182
183  rsaref_to_gmp(output, output_data, output_len);
184}
185
186#else /* RSAREF */
187
188/* Encrypt input using the public key.  Input should be a 256 bit value. */
189
190void rsa_public_encrypt(MP_INT *output, MP_INT *input, RSAPublicKey *key,
191                        RandomState *state)
192{
193  MP_INT aux;
194  unsigned int i, input_bits, input_len, len;
195
196  if (mpz_cmp_ui(&(key->e), 3) < 0)
197    fatal("Bad public key, POTENTIAL BREAK-IN ATTEMPT!");
198  input_bits = mpz_sizeinbase(input, 2);
199  input_len = (input_bits + 7) / 8;
200  len = (key->bits + 7) / 8;
201
202  assert(len >= input_len + 3);
203 
204  mpz_init_set_ui(&aux, 2);
205  for (i = 2; i < len - input_len - 1; i++)
206    {
207      unsigned int byte;
208      do
209        byte = random_get_byte(state);
210      while (byte == 0);
211      mpz_mul_2exp(&aux, &aux, 8);
212      mpz_add_ui(&aux, &aux, byte);
213    }
214  mpz_mul_2exp(&aux, &aux, 8 * (input_len + 1));
215  mpz_add(&aux, &aux, input);
216
217  rsa_public(output, &aux, key);
218  mpz_clear(&aux);
219}
220
221/* Decrypt input using the private key.  Output will become a 256 bit value. */
222
223void rsa_private_decrypt(MP_INT *output, MP_INT *input, RSAPrivateKey *key)
224{
225  MP_INT aux;
226  unsigned int len, i;
227  unsigned char *value;
228
229  rsa_private(output, input, key);
230
231  len = (key->bits + 7) / 8;
232  value = xmalloc(len);
233
234  mpz_init_set(&aux, output);
235  for (i = len; i >= 4; i -= 4)
236    {
237      unsigned int limb = mpz_get_ui(&aux);
238      PUT_32BIT(value + i - 4, limb);
239      mpz_div_2exp(&aux, &aux, 32);
240    }
241  for (; i > 0; i--)
242    {
243      value[i - 1] = mpz_get_ui(&aux);
244      mpz_div_2exp(&aux, &aux, 8);
245    }
246  mpz_clear(&aux);
247
248  if (value[0] != 0 || value[1] != 2)
249    fatal("Bad result from rsa_private_decrypt");
250
251  for (i = 2; i < len && value[i]; i++)
252    ;
253
254  xfree(value);
255 
256  mpz_mod_2exp(output, output, 8 * (len - i - 1));
257}
258
259#endif /* RSAREF */
Note: See TracBrowser for help on using the repository browser.