comparison rsa.c @ 0:d7da3b1e1540 libtomcrypt

put back the 0.95 makefile which was inadvertently merged over
author Matt Johnston <matt@ucc.asn.au>
date Mon, 31 May 2004 18:21:40 +0000
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:d7da3b1e1540
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, [email protected], 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