~ubuntu-branches/ubuntu/utopic/dropbear/utopic-proposed

« back to all changes in this revision

Viewing changes to libtomcrypt/rsa.c

  • Committer: Bazaar Package Importer
  • Author(s): Matt Johnston
  • Date: 2005-12-08 19:20:21 UTC
  • mfrom: (1.2.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20051208192021-nyp9rwnt77nsg6ty
Tags: 0.47-1
* New upstream release.
* SECURITY: Fix incorrect buffer sizing.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
2
 
 *
3
 
 * LibTomCrypt is a library that provides various cryptographic
4
 
 * algorithms in a highly modular and flexible manner.
5
 
 *
6
 
 * The library is free for all purposes without any express
7
 
 * guarantee it works.
8
 
 *
9
 
 * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org
10
 
 */
11
 
 
12
 
/* RSA Code by Tom St Denis */
13
 
#include "mycrypt.h"
14
 
 
15
 
#ifdef MRSA
16
 
 
17
 
int rsa_signpad(const unsigned char *in,  unsigned long inlen,
18
 
                      unsigned char *out, unsigned long *outlen)
19
 
{
20
 
   unsigned long x, y;
21
 
 
22
 
   _ARGCHK(in     != NULL);
23
 
   _ARGCHK(out    != NULL);
24
 
   _ARGCHK(outlen != NULL);
25
 
 
26
 
   if (*outlen < (3 * inlen)) {
27
 
      return CRYPT_BUFFER_OVERFLOW;
28
 
   }
29
 
 
30
 
   /* check inlen */
31
 
   if (inlen > MAX_RSA_SIZE/8) {
32
 
      return CRYPT_PK_INVALID_SIZE;
33
 
   }
34
 
 
35
 
   for (y = x = 0; x < inlen; x++)
36
 
       out[y++] = (unsigned char)0xFF;
37
 
   for (x = 0; x < inlen; x++)
38
 
       out[y++] = in[x];
39
 
   for (x = 0; x < inlen; x++)
40
 
       out[y++] = (unsigned char)0xFF;
41
 
   *outlen = 3 * inlen;
42
 
   return CRYPT_OK;
43
 
}
44
 
 
45
 
int rsa_pad(const unsigned char *in,  unsigned long inlen,
46
 
                  unsigned char *out, unsigned long *outlen,
47
 
                  int wprng, prng_state *prng)
48
 
{
49
 
   unsigned char buf[3*(MAX_RSA_SIZE/8)];
50
 
   unsigned long x;
51
 
   int err;
52
 
 
53
 
   _ARGCHK(in     != NULL);
54
 
   _ARGCHK(out    != NULL);
55
 
   _ARGCHK(outlen != NULL);
56
 
 
57
 
   /* is output big enough? */
58
 
   if (*outlen < (3 * inlen)) {
59
 
      return CRYPT_BUFFER_OVERFLOW;
60
 
   }
61
 
 
62
 
   /* get random padding required */
63
 
   if ((err = prng_is_valid(wprng)) != CRYPT_OK) {
64
 
      return err;
65
 
   }
66
 
 
67
 
   /* check inlen */
68
 
   if (inlen > (MAX_RSA_SIZE/8)) {
69
 
      return CRYPT_PK_INVALID_SIZE;
70
 
   }
71
 
 
72
 
   if (prng_descriptor[wprng].read(buf, inlen*2-2, prng) != (inlen*2 - 2))  {
73
 
       return CRYPT_ERROR_READPRNG;
74
 
   }
75
 
 
76
 
   /* pad it like a sandwhich
77
 
    *
78
 
    * Looks like 0xFF R1 M R2 0xFF
79
 
    *
80
 
    * Where R1/R2 are random and exactly equal to the length of M minus one byte.
81
 
    */
82
 
   for (x = 0; x < inlen-1; x++) {
83
 
       out[x+1] = buf[x];
84
 
   }
85
 
 
86
 
   for (x = 0; x < inlen; x++) {
87
 
       out[x+inlen] = in[x];
88
 
   }
89
 
 
90
 
   for (x = 0; x < inlen-1; x++) {
91
 
       out[x+inlen+inlen] = buf[x+inlen-1];
92
 
   }
93
 
 
94
 
   /* last and first bytes are 0xFF */
95
 
   out[0] = out[inlen+inlen+inlen-1] = (unsigned char)0xFF;
96
 
 
97
 
   /* clear up and return */
98
 
#ifdef CLEAN_STACK
99
 
   zeromem(buf, sizeof(buf));
100
 
#endif
101
 
   *outlen = inlen*3;
102
 
   return CRYPT_OK;
103
 
}
104
 
 
105
 
int rsa_signdepad(const unsigned char *in,  unsigned long inlen,
106
 
                        unsigned char *out, unsigned long *outlen)
107
 
{
108
 
   unsigned long x;
109
 
 
110
 
   _ARGCHK(in     != NULL);
111
 
   _ARGCHK(out    != NULL);
112
 
   _ARGCHK(outlen != NULL);
113
 
 
114
 
   if (*outlen < inlen/3) {
115
 
      return CRYPT_BUFFER_OVERFLOW;
116
 
   }
117
 
 
118
 
   /* check padding bytes */
119
 
   for (x = 0; x < inlen/3; x++) {
120
 
       if (in[x] != (unsigned char)0xFF || in[x+(inlen/3)+(inlen/3)] != (unsigned char)0xFF) {
121
 
          return CRYPT_INVALID_PACKET;
122
 
       }
123
 
   }
124
 
   for (x = 0; x < inlen/3; x++) {
125
 
       out[x] = in[x+(inlen/3)];
126
 
   }
127
 
   *outlen = inlen/3;
128
 
   return CRYPT_OK;
129
 
}
130
 
 
131
 
int rsa_depad(const unsigned char *in,  unsigned long inlen,
132
 
                    unsigned char *out, unsigned long *outlen)
133
 
{
134
 
   unsigned long x;
135
 
 
136
 
   _ARGCHK(in     != NULL);
137
 
   _ARGCHK(out    != NULL);
138
 
   _ARGCHK(outlen != NULL);
139
 
 
140
 
   if (*outlen < inlen/3) {
141
 
      return CRYPT_BUFFER_OVERFLOW;
142
 
   }
143
 
   for (x = 0; x < inlen/3; x++) {
144
 
       out[x] = in[x+(inlen/3)];
145
 
   }
146
 
   *outlen = inlen/3;
147
 
   return CRYPT_OK;
148
 
}
149
 
 
150
 
int rsa_export(unsigned char *out, unsigned long *outlen, int type, rsa_key *key)
151
 
{
152
 
   unsigned long y, z; 
153
 
   int err;
154
 
 
155
 
   _ARGCHK(out    != NULL);
156
 
   _ARGCHK(outlen != NULL);
157
 
   _ARGCHK(key    != NULL);
158
 
   
159
 
   /* can we store the static header?  */
160
 
   if (*outlen < (PACKET_SIZE + 1)) {
161
 
      return CRYPT_BUFFER_OVERFLOW;
162
 
   }   
163
 
 
164
 
   /* type valid? */
165
 
   if (!(key->type == PK_PRIVATE || key->type == PK_PRIVATE_OPTIMIZED) &&
166
 
        (type == PK_PRIVATE || type == PK_PRIVATE_OPTIMIZED)) {
167
 
      return CRYPT_PK_INVALID_TYPE;
168
 
   }
169
 
 
170
 
   /* start at offset y=PACKET_SIZE */
171
 
   y = PACKET_SIZE;
172
 
 
173
 
   /* output key type */
174
 
   out[y++] = type;
175
 
 
176
 
   /* output modulus */
177
 
   OUTPUT_BIGNUM(&key->N, out, y, z);
178
 
 
179
 
   /* output public key */
180
 
   OUTPUT_BIGNUM(&key->e, out, y, z);
181
 
 
182
 
   if (type == PK_PRIVATE || type == PK_PRIVATE_OPTIMIZED) {
183
 
      OUTPUT_BIGNUM(&key->d, out, y, z);
184
 
   }
185
 
 
186
 
   if (type == PK_PRIVATE_OPTIMIZED) {
187
 
      OUTPUT_BIGNUM(&key->dQ, out, y, z);
188
 
      OUTPUT_BIGNUM(&key->dP, out, y, z);
189
 
      OUTPUT_BIGNUM(&key->pQ, out, y, z);
190
 
      OUTPUT_BIGNUM(&key->qP, out, y, z);
191
 
      OUTPUT_BIGNUM(&key->p, out, y, z);
192
 
      OUTPUT_BIGNUM(&key->q, out, y, z);
193
 
   }
194
 
 
195
 
   /* store packet header */
196
 
   packet_store_header(out, PACKET_SECT_RSA, PACKET_SUB_KEY);
197
 
 
198
 
   /* copy to the user buffer */
199
 
   *outlen = y;
200
 
 
201
 
   /* clear stack and return */
202
 
   return CRYPT_OK;
203
 
}
204
 
 
205
 
int rsa_import(const unsigned char *in, unsigned long inlen, rsa_key *key)
206
 
{
207
 
   unsigned long x, y;
208
 
   int err;
209
 
 
210
 
   _ARGCHK(in  != NULL);
211
 
   _ARGCHK(key != NULL);
212
 
 
213
 
   /* check length */
214
 
   if (inlen < (1+PACKET_SIZE)) {
215
 
      return CRYPT_INVALID_PACKET;
216
 
   }
217
 
 
218
 
   /* test packet header */
219
 
   if ((err = packet_valid_header((unsigned char *)in, PACKET_SECT_RSA, PACKET_SUB_KEY)) != CRYPT_OK) {
220
 
      return err;
221
 
   }
222
 
 
223
 
   /* init key */
224
 
   if ((err = mp_init_multi(&key->e, &key->d, &key->N, &key->dQ, &key->dP, &key->qP,
225
 
                     &key->pQ, &key->p, &key->q, NULL)) != MP_OKAY) {
226
 
      return mpi_to_ltc_error(err);
227
 
   }
228
 
 
229
 
   /* get key type */
230
 
   y = PACKET_SIZE;
231
 
   key->type = (int)in[y++];
232
 
 
233
 
   /* load the modulus  */
234
 
   INPUT_BIGNUM(&key->N, in, x, y, inlen);
235
 
 
236
 
   /* load public exponent */
237
 
   INPUT_BIGNUM(&key->e, in, x, y, inlen);
238
 
 
239
 
   /* get private exponent */
240
 
   if (key->type == PK_PRIVATE || key->type == PK_PRIVATE_OPTIMIZED) {
241
 
      INPUT_BIGNUM(&key->d, in, x, y, inlen);
242
 
   }
243
 
 
244
 
   /* get CRT private data if required */
245
 
   if (key->type == PK_PRIVATE_OPTIMIZED) {
246
 
      INPUT_BIGNUM(&key->dQ, in, x, y, inlen);
247
 
      INPUT_BIGNUM(&key->dP, in, x, y, inlen);
248
 
      INPUT_BIGNUM(&key->pQ, in, x, y, inlen);
249
 
      INPUT_BIGNUM(&key->qP, in, x, y, inlen);
250
 
      INPUT_BIGNUM(&key->p, in, x, y, inlen);
251
 
      INPUT_BIGNUM(&key->q, in, x, y, inlen);
252
 
   }
253
 
 
254
 
   /* free up ram not required */
255
 
   if (key->type != PK_PRIVATE_OPTIMIZED) {
256
 
      mp_clear_multi(&key->dQ, &key->dP, &key->pQ, &key->qP, &key->p, &key->q, NULL);
257
 
   }
258
 
   if (key->type != PK_PRIVATE && key->type != PK_PRIVATE_OPTIMIZED) {
259
 
      mp_clear(&key->d);
260
 
   }
261
 
 
262
 
   return CRYPT_OK;
263
 
error:
264
 
   mp_clear_multi(&key->d, &key->e, &key->N, &key->dQ, &key->dP,
265
 
                  &key->pQ, &key->qP, &key->p, &key->q, NULL);
266
 
   return err;
267
 
}
268
 
 
269
 
#include "rsa_sys.c"
270
 
 
271
 
#endif /* RSA */
272
 
 
273