|
|
1.1.1.2 root 1: /*
2: * rsaglue2.c - These functions wrap and unwrap message digests (MDs) and
3: * data encryption keys (DEKs) in padding and RSA-encrypt them into
1.1.1.3 ! root 4: * multi-precision integers. This layer of abstraction was introduced
! 5: * to allow the transparent use of either the RSAREF Cryptographic
! 6: * Toolkit from RSA Data Security Inc for the RSA calculations (where
! 7: * the RSA patent applies), or, by using a different version of this
! 8: * rsaglue module, we can use Philip Zimmermann's mpi library for the
! 9: * RSA calculations. The rsaglue.c module from PGP version 2.3a performs
! 10: * the same functions as this module, but can be compiled to select the
! 11: * use of mpilib functions instead of RSAREF as the underlying math engine.
! 12: * That version of rsaglue.c would be suitable where the RSA patent does
! 13: * not apply, such as Canada.
1.1.1.2 root 14: *
15: * This file uses RSAREF to perform the actual encryption and decryption.
1.1.1.3 ! root 16: * It must be linked with the RSAREF library (rsaref.a, rsaref.lib,
1.1.1.2 root 17: * or whatever it's called on your system) to function.
18: *
19: * This code only accepts PKCS-style padding. Sorry, folks, but the
20: * RSAREF routines won't do it any other way. This will cause some
21: * older messages and signatures trouble.
22: * See pgformat.doc for a detailed description of the formats.
23: *
24: * (c) Copyright 1990-1994 by Philip Zimmermann. All rights reserved.
25: * The author assumes no liability for damages resulting from the use
26: * of this software, even if the damage results from defects in this
27: * software. No warranty is expressed or implied.
28: *
29: * Note that while most PGP source modules bear Philip Zimmermann's
30: * copyright notice, many of them have been revised or entirely written
31: * by contributors who frequently failed to put their names in their
32: * code. Code that has been incorporated into PGP from other authors
33: * was either originally published in the public domain or is used with
34: * permission from the various authors.
35: *
36: * PGP is available for free to the public under certain restrictions.
37: * See the PGP User's Guide (included in the release package) for
38: * important information about licensing, patent restrictions on
39: * certain algorithms, trademarks, copyrights, and export controls.
40: */
41:
42: #include <string.h> /* for mem*() */
43: #include <assert.h>
44: #include "mpilib.h"
45: #include "mpiio.h"
46: #include "pgp.h"
47: #include "rsaglue.h"
48: #include "random.h" /* for cryptRandByte() */
49: #include "language.h" /* for _LANG() */
50:
1.1.1.3 ! root 51: char signon_legalese[] =
! 52: _LANG("Distributed by the Massachusetts Institute of Technology. \
! 53: Uses RSAREF.\n");
1.1.1.2 root 54:
55: #include <global.h>
56: #include <rsaref.h>
57: #include <rsa.h>
58: /*
59: * The functions we call in rsa.h are:
60: *
61: * int RSAPublicEncrypt PROTO_LIST
62: * ((unsigned char *, unsigned int *, unsigned char *, unsigned int,
63: * R_RSA_PUBLIC_KEY *, R_RANDOM_STRUCT *));
64: * int RSAPrivateEncrypt PROTO_LIST
65: * ((unsigned char *, unsigned int *, unsigned char *, unsigned int,
66: * R_RSA_PRIVATE_KEY *));
67: * int RSAPublicDecrypt PROTO_LIST
68: * ((unsigned char *, unsigned int *, unsigned char *, unsigned int,
69: * R_RSA_PUBLIC_KEY *));
70: * int RSAPrivateDecrypt PROTO_LIST
71: * ((unsigned char *, unsigned int *, unsigned char *, unsigned int,
72: * R_RSA_PRIVATE_KEY *));
73: */
74:
75: /* Functions to convert to and from RSAREF's bignum formats */
76:
77: void
78: rsaref2reg (unitptr to, byte *from, int frombytes)
79: /* Convert an RSAREF-style MSB-first array of bytes to an mpi-style
80: * native-byte-order integer. (global_precision units long.)
81: */
82: {
83: int tobytes;
84:
85: tobytes = units2bytes (global_precision);
86: if (tobytes > frombytes) {
87: memset(to, 0, tobytes - frombytes);
88: memcpy((byte *)to + tobytes - frombytes, from, frombytes);
89: } else {
90: memcpy((byte *)to, from + frombytes - tobytes, tobytes);
91: }
92: #ifndef HIGHFIRST
93: hiloswap((byte *)to, tobytes);
94: #endif
95: } /* rsaref2reg */
96:
97: void
98: reg2rsaref (byte *to, int tobytes, unitptr from)
99: /* Convert the other way, mpi format to an array of bytes. */
100: {
101: int frombytes;
102:
103: frombytes = units2bytes(global_precision);
104:
105: #ifdef HIGHFIRST
106: if (tobytes > frombytes) {
107: memset(to, 0, tobytes-frombytes);
108: memcpy(to + tobytes - frombytes, (byte *)from, frombytes);
109: } else {
110: memcpy(to, (byte *)from + frombytes - tobytes, tobytes);
111: }
112: #else
113: if (tobytes > frombytes) {
114: memcpy(to, (byte *)from, frombytes);
115: memset(to + frombytes, 0, tobytes-frombytes);
116: } else {
117: memcpy(to, (byte *)from, tobytes);
118: }
119: hiloswap(to, tobytes);
120: #endif
121: } /* reg2rsaref */
122:
123: int
124: make_RSA_PUBLIC_KEY(R_RSA_PUBLIC_KEY *rpk, unitptr e, unitptr n)
125: /* Given mpi's e and n, fill in an R_RSA_PUBLIC_KEY structure.
126: * Returns -3 on error (key too big), 0 on success
127: */
128: {
129: rpk->bits = countbits(n);
130:
131: if (rpk->bits > MAX_RSA_MODULUS_BITS)
132: return -3;
133:
134: reg2rsaref(rpk->modulus, MAX_RSA_MODULUS_LEN, n);
135: reg2rsaref(rpk->exponent, MAX_RSA_MODULUS_LEN, e);
136: return 0;
137: } /* make_RSA_PUBLIC_KEY */
138:
139: /* Returns -1 on error, 0 on success */
140: int
141: make_RSA_PRIVATE_KEY(R_RSA_PRIVATE_KEY *rpk, unitptr e, unitptr d, unitptr p,
142: unitptr q, unitptr dp, unitptr dq, unitptr u, unitptr n)
143: /* Given a number of necessary mpi's, fill in an R_RSA_PRIVATE_KEY structure.
144: * Returns -3 on error (key too big), 0 on success
145: */
146: {
147: rpk->bits = countbits(n);
148:
149: if (rpk->bits > MAX_RSA_MODULUS_BITS ||
150: countbits(p) > MAX_RSA_PRIME_BITS ||
151: countbits(q) > MAX_RSA_PRIME_BITS)
152: return -3;
153:
154: reg2rsaref(rpk->modulus, MAX_RSA_MODULUS_LEN, n);
155: reg2rsaref(rpk->publicExponent, MAX_RSA_MODULUS_LEN, e);
156: reg2rsaref(rpk->exponent, MAX_RSA_MODULUS_LEN, d);
157: /* The larger prime (p) first */
158: reg2rsaref(rpk->prime[0], MAX_RSA_PRIME_LEN, q);
159: reg2rsaref(rpk->prime[1], MAX_RSA_PRIME_LEN, p);
160: /* d mod (p-1) and d mod (q-1) */
161: reg2rsaref(rpk->primeExponent[0], MAX_RSA_PRIME_LEN, dq);
162: reg2rsaref(rpk->primeExponent[1], MAX_RSA_PRIME_LEN, dp);
163: /* 1/q mod p */
164: reg2rsaref(rpk->coefficient, MAX_RSA_PRIME_LEN, u);
165: return 0;
166: } /* make_RSA_PRIVATE_KEY */
167:
168: /*
169: * These functions hide all the internal details of RSA-encrypted
170: * keys and digests.
171: */
172:
173: /* Abstract Syntax Notation One (ASN.1) Distinguished Encoding Rules (DER)
174: encoding for RSA/MD5, used in PKCS-format signatures. */
175: static byte asn_array[] = { /* PKCS 01 block type 01 data */
176: 0x30,0x20,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
177: 0x02,0x05,0x05,0x00,0x04,0x10 };
178: /* This many bytes from the end, there's a zero byte */
179: #define ASN_ZERO_END 3
180:
181: int
182: rsa_public_encrypt(unitptr outbuf, byteptr inbuf, short bytes,
183: unitptr E, unitptr N)
184: /* Encrypt a DEK with a public key. Returns 0 on success.
185: * <0 means there was an error.
186: * -1: Generic error
187: * -3: Key too big
188: * -4: Key too small
189: */
190: {
191: unit temp[MAX_UNIT_PRECISION];
192: unsigned int blocksize;
193: int i; /* Temporary, and holds error codes */
194: R_RSA_PUBLIC_KEY PubKey;
195: R_RANDOM_STRUCT Random;
196:
197: /* Fill in the R_RSA_PUBLIC_KEY structure as needed later. */
198: i = make_RSA_PUBLIC_KEY(&PubKey, E, N);
199: if (i < 0)
200: return i;
201:
202: /* The RSAREF routines have their own random number generator
203: * to generate random padding. The following code seeds it
204: * from PGP's random number generator.
205: */
206: R_RandomInit(&Random);
207: for (;;) {
208: /* Bytes needed is an unsigned int */
209: R_GetRandomBytesNeeded(&blocksize, &Random);
210: if (!blocksize)
211: break;
212: if (blocksize > sizeof(temp))
213: blocksize = sizeof(temp);
214: for (i = 0; i < blocksize; i++)
215: ((byte *)temp)[i] = cryptRandByte();
216: R_RandomUpdate(&Random, (byte *)temp, blocksize);
217:
218: }
219: /* Pad and encrypt */
220: i = RSAPublicEncrypt((byte *)temp, &blocksize,
221: inbuf, bytes, &PubKey, &Random);
222: R_RandomFinal(&Random); /* Clean up RSAREF's RNG */
223: burn(Random); /* Just to be sure */
224:
225: if (i)
226: i = (i == RE_LEN) ? -4 : -1;
227:
228: rsaref2reg(outbuf, (byte *)temp, blocksize);
229:
230: Cleanup:
231: mp_burn(temp);
232: burn(PubKey);
233: return i < 0 ? i : 0;
234: } /* rsa_public_encrypt */
235:
236: int
237: rsa_private_encrypt(unitptr outbuf, byteptr inbuf, short bytes,
238: unitptr E, unitptr D, unitptr P, unitptr Q, unitptr U, unitptr N)
239: /* Encrypt a message digest with a private key.
240: * Returns <0 on error:
241: * -1: generic error
242: * -3: Key too big
243: * -4: Key too small
244: */
245: {
246: unit temp[MAX_UNIT_PRECISION];
247: unit DP[MAX_UNIT_PRECISION], DQ[MAX_UNIT_PRECISION];
248: R_RSA_PRIVATE_KEY PrivKey;
249: byte *p;
250: int i;
251: unsigned int blocksize;
252:
253: /* PGP doesn't store these coefficents, so we need to compute them. */
254: mp_move(temp,P);
255: mp_dec(temp);
256: mp_mod(DP,D,temp);
257: mp_move(temp,Q);
258: mp_dec(temp);
259: mp_mod(DQ,D,temp);
260:
261: p = (byte *)temp;
262:
263: i = make_RSA_PRIVATE_KEY(&PrivKey, E, D, P, Q, DP, DQ, U, N);
264: if (i < 0)
265: goto Cleanup;
266: memcpy(p, asn_array, sizeof(asn_array)); /* ASN data */
267: p += sizeof(asn_array);
268: memcpy(p, inbuf, bytes); /* User data */
269: /* Pad and encrypt */
270: i = RSAPrivateEncrypt((byte *)temp, &blocksize,
271: (byte *)temp, bytes+sizeof(asn_array), &PrivKey);
272: burn(PrivKey);
273: if (i)
274: i = (i == RE_LEN) ? -4 : -1;
275:
276: rsaref2reg(outbuf, (byte *)temp, blocksize);
277:
278: Cleanup:
279: burn(temp);
280:
281: return i;
282: } /* rsa_private_encrypt */
283:
284: /* Remove a signature packet from an MPI */
285: /* Thus, we expect constant padding and the MIC ASN sequence */
286: int
287: rsa_public_decrypt(byteptr outbuf, unitptr inbuf,
288: unitptr E, unitptr N)
289: /* Decrypt a message digest using a public key. Returns the number of bytes
290: * extracted, or <0 on error.
291: * -1: Corrupted packet.
292: * -3: Key too big
293: * -4: Key too small
294: * -5: Maybe malformed RSA packet
295: * -7: Unknown conventional algorithm
296: * -9: Malformed RSA packet
297: */
298: {
299: R_RSA_PUBLIC_KEY PubKey;
300: unit temp[MAX_UNIT_PRECISION];
301: unsigned int blocksize;
302: int i;
303: byte *front, *back;
304:
305: i = make_RSA_PUBLIC_KEY(&PubKey, E, N);
306: if (i < 0)
307: return i;
308: blocksize = countbytes(inbuf);
309: reg2rsaref((byte *)temp, blocksize, inbuf);
310:
311: i = RSAPublicDecrypt((byte *)temp, &blocksize,
312: (byte *)temp, blocksize, &PubKey);
313: burn(PubKey);
314: if (i) {
315: mp_burn(temp);
316: if (i == RE_LEN)
317: return -4;
318: if (i == RE_DATA)
319: return -5;
320: return -1;
321: }
322: front = (byte *)temp;
323: back = front+blocksize;
324:
325: if (memcmp(front, asn_array, sizeof(asn_array))) {
326: mp_burn(temp);
327: return -7;
328: }
329: front += sizeof(asn_array);
330:
331: /* We're done - copy user data to outbuf */
332: if (back < front)
333: goto ErrorReturn;
334: blocksize = back-front;
335: memcpy(outbuf, front, blocksize);
336: mp_burn(temp);
337: return blocksize;
338: ErrorReturn:
339: mp_burn(temp);
340: return -9;
341: } /* rsa_public_decrypt */
342:
343: /* We expect to find random padding and an encryption key */
344: int
345: rsa_private_decrypt(byteptr outbuf, unitptr inbuf,
346: unitptr E, unitptr D, unitptr P, unitptr Q, unitptr U, unitptr N)
347: /* Decrypt an encryption key using a private key. Returns the number of bytes
348: * extracted, or <0 on error.
349: * -1: Generic error
350: * -3: Key too big
351: * -4: Key too small
352: * -5: Maybe malformed RSA
353: * -7: Unknown conventional algorithm
354: * -9: Malformed RSA packet
355: */
356: {
357: R_RSA_PRIVATE_KEY PrivKey;
358: byte *front;
359: unsigned int blocksize;
360: unit temp[MAX_UNIT_PRECISION];
361: unit DP[MAX_UNIT_PRECISION], DQ[MAX_UNIT_PRECISION];
362: int i;
363:
364: /* PGP doesn't store (d mod p-1) and (d mod q-1), so compute 'em */
365: mp_move(temp,P);
366: mp_dec(temp);
367: mp_mod(DP,D,temp);
368: mp_move(temp,Q);
369: mp_dec(temp);
370: mp_mod(DQ,D,temp);
371:
372: i = make_RSA_PRIVATE_KEY(&PrivKey, E, D, P, Q, DP, DQ, U, N);
373: mp_burn(DP);
374: mp_burn(DQ);
375: mp_burn(temp);
376:
377: if (i < 0)
378: return i;
379:
380: blocksize = countbytes(inbuf);
381: reg2rsaref((byte *)temp, blocksize, inbuf);
382: i = RSAPrivateDecrypt((byte *)temp, &blocksize,
383: (byte *)temp, blocksize, &PrivKey);
384: burn(PrivKey);
385: if (i) {
386: if (i == RE_LEN)
387: return -4;
388: if (i == RE_DATA)
389: return -5;
390: return -1;
391: }
392: front = (byte *)temp; /* Start of block */
393:
394: memcpy(outbuf, front, blocksize);
395: mp_burn(temp);
396: return blocksize;
397:
398: Corrupted:
399: mp_burn(temp);
400: return -9;
401: } /* rsa_private_decrypt */
402:
403: /*
404: * Stub to replace RSAREF's NN_ModExp with a call to the mpilib's
405: * faster mp_modexp. (A bit over 3x faster on an IBM PC.)
406: * It's too bad that RSAREF's NN routines are pretty clean, while the
1.1.1.3 ! root 407: * mpilib is a hard-to-follow kludge. But the mpilib is pretty fast,
! 408: * especially on 16-bit machines, so the kludginess is forgivable.
! 409: * Note that we are still using RSAREF, but we are just using a faster
! 410: * modulo exponentiation routine.
1.1.1.2 root 411: * If you comment out the following block of code, you get a (much slower)
412: * pure RSAREF version.
413: */
414: #ifdef USEMPILIB
415:
416: /*
417: * The mpilib keeps numbers in native byte order, in arrays global_precision
418: * "units" long. RSAREF keeps numbers in little-endian arrays of 32-bit
419: * "digits".
420: */
421: static void
422: nn2mpi(unit *mpi, word32 *nn, unsigned nndigits)
423: {
424: /* nndigits must be <= global_precision */
425: unsigned i;
426: word32 *p;
427:
428: assert((units2bytes(global_precision) & 3) == 0);
429: i = units2bytes(global_precision) >> 2;
430: if (nndigits > i)
431: nndigits = i;
432: i -= nndigits;
433:
434: #ifdef HIGHFIRST
435: p = (word32 *)(mpi+global_precision);
436: while (nndigits--)
437: *--p = *nn++;
438: while (i--)
439: *--p = 0;
440: #else
441: p = (word32 *)mpi;
442: while (nndigits--)
443: *p++ = *nn++;
444: while (i--)
445: *p++ = 0;
446: #endif
447: }
448:
449: static void
450: mpi2nn(word32 *nn, unsigned nndigits, unit *mpi)
451: {
452: /* nndigits must be >= global_precision */
453: unsigned i;
454: word32 *p;
455:
456: assert((units2bytes(global_precision) & 3) == 0);
457: i = units2bytes(global_precision) >> 2;
458: if (i > nndigits)
459: i = nndigits;
460: nndigits -= i;
461:
462: #ifdef HIGHFIRST
463: p = (word32 *)(mpi+global_precision);
464: while (i--)
465: *nn++ = *--p;
466: #else
467: p = (word32 *)mpi;
468: while (i--)
469: *nn++ = *p++;
470: #endif
471: while (nndigits--)
472: *nn++ = 0;
473: }
474:
475: void
476: NN_ModExp(word32 *result, word32 *base, word32 *exponent, unsigned expdigits,
477: word32 *modulus, unsigned moddigits)
478: {
479: unit a[MAX_UNIT_PRECISION], b[MAX_UNIT_PRECISION];
480: unit c[MAX_UNIT_PRECISION], d[MAX_UNIT_PRECISION];
481: int i;
482: unsigned oldprecision;
483:
484: oldprecision = global_precision;
485: set_precision(MAX_UNIT_PRECISION);
486:
487: nn2mpi(b, base, moddigits);
488: nn2mpi(c, exponent, expdigits);
489: nn2mpi(d, modulus, moddigits);
490:
491: i = mp_modexp(a, b, c, d);
492: assert(i == 0);
493: mpi2nn(result, moddigits, a);
494: set_precision(oldprecision);
495: }
496:
497: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.