|
|
1.1 root 1: /*
2: * rsaglue1.c - These functions wrap and unwrap message digests (MDs) and
3: * data encryption keys (DEKs) in padding and RSA-encrypt them into
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, Philip Zimmermann's mpi library for the
8: * RSA calculations. The rsaglue.c module from PGP version 2.3a performs
9: * the same functions as this module, but can be compiled to select the
10: * use of mpilib functions instead of RSAREF as the underlying math engine.
11: * That version of rsaglue.c would be suitable where the RSA patent does
12: * not apply, such as Canada.
13: *
14: * This file uses MPILIB to perform the actual encryption and decryption.
15: * It uses the same PKCS format as RSAREF, although it also accepts an older
16: * format used in PGP 2.1.
17: *
18: * (c) Copyright 1990-1994 by Philip Zimmermann. All rights reserved.
19: * The author assumes no liability for damages resulting from the use
20: * of this software, even if the damage results from defects in this
21: * software. No warranty is expressed or implied.
22: *
23: * Note that while most PGP source modules bear Philip Zimmermann's
24: * copyright notice, many of them have been revised or entirely written
25: * by contributors who frequently failed to put their names in their
26: * code. Code that has been incorporated into PGP from other authors
27: * was either originally published in the public domain or is used with
28: * permission from the various authors.
29: *
30: * PGP is available for free to the public under certain restrictions.
31: * See the PGP User's Guide (included in the release package) for
32: * important information about licensing, patent restrictions on
33: * certain algorithms, trademarks, copyrights, and export controls.
34: */
35:
36: #include <string.h> /* for mem*() */
37: #include "mpilib.h"
38: #include "mpiio.h"
39: #include "pgp.h"
40: #include "rsaglue.h"
41: #include "random.h" /* for cryptRandByte() */
42:
43: /* No RSADSI credit for MPI version */
44: char signon_legalese[] = "";
45:
46: /* These functions hide all the internal details of RSA-encrypted
47: * keys and digests. They owe a lot of their heritage to
48: * the preblock() and postunblock() routines in mpiio.c.
49: */
50:
51: /* Abstract Syntax Notation One (ASN.1) Distinguished Encoding Rules (DER)
52: encoding for RSA/MD5, used in PKCS-format signatures. */
53: static byte asn_array[] = { /* PKCS 01 block type 01 data */
54: 0x30,0x20,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
55: 0x02,0x05,0x05,0x00,0x04,0x10 };
56: /* This many bytes from the end, there's a zero byte */
57: #define ASN_ZERO_END 3
58:
59: int
60: rsa_public_encrypt(unitptr outbuf, byteptr inbuf, short bytes,
61: unitptr E, unitptr N)
62: /* Encrypt a DEK with a public key. Returns 0 on success.
63: * <0 means there was an error.
64: * -1: Generic error
65: * -3: Key too big
66: * -4: Key too small
67: */
68: {
69: unit temp[MAX_UNIT_PRECISION];
70: unsigned int blocksize;
71: int i; /* Temporary, and holds error codes */
72: byte *p = (byte *)temp;
73:
74: /*
75: * We are building the mpi in place, except for a possible
76: * byte-order swap to little-endian at the end. Thus, we
77: * need to fill the buffer with leading 0's in the unused
78: * most significant byte positions.
79: */
80: blocksize = countbytes(N) - 1; /* Bytes available for user data */
81: for (i = units2bytes(global_precision) - blocksize; i > 0; --i)
82: *p++ = 0;
83: /*
84: * Both the PKCS and PGP 2.0 key formats add a type byte, and a
85: * a framing byte of 0 to the user data. The remaining space
86: * is filled with random padding. (PKCS requires that there be
87: * at least 1 byte of padding.)
88: */
89: i = blocksize - 2 - bytes;
90:
91: if (i < 1) /* Less than minimum padding? */
92: return -4;
93: *p++ = CK_ENCRYPTED_BYTE; /* Type byte */
94: while (i) /* Non-zero random padding */
95: if ((*p = cryptRandByte()))
96: ++p, --i;
97: *p++ = 0; /* Framing byte */
98: memcpy(p, inbuf, bytes); /* User data */
99:
100: mp_convert_order((byte *)temp); /* Convert buffer to MPI */
101: i = mp_modexp(outbuf, temp, E, N); /* Do the encryption */
102: if (i < 0)
103: i == -1;
104:
105: Cleanup:
106: mp_burn(temp);
107: return i < 0 ? i : 0;
108: } /* rsa_public_encrypt */
109:
110: int
111: rsa_private_encrypt(unitptr outbuf, byteptr inbuf, short bytes,
112: unitptr E, unitptr D, unitptr P, unitptr Q, unitptr U, unitptr N)
113: /* Encrypt a message digest with a private key.
114: * Returns <0 on error:
115: * -1: generic error
116: * -4: Key too big
117: * -5: Key too small
118: */
119: {
120: unit temp[MAX_UNIT_PRECISION];
121: unit DP[MAX_UNIT_PRECISION], DQ[MAX_UNIT_PRECISION];
122: byte *p;
123: int i;
124: unsigned int blocksize;
125:
126: /* PGP doesn't store these coefficents, so we need to compute them. */
127: mp_move(temp,P);
128: mp_dec(temp);
129: mp_mod(DP,D,temp);
130: mp_move(temp,Q);
131: mp_dec(temp);
132: mp_mod(DQ,D,temp);
133:
134: p = (byte *)temp;
135:
136:
137: /* We are building the mpi in place, except for a possible
138: * byte-order swap to little-endian at the end. Thus, we
139: * need to fill the buffer with leading 0's in the unused
140: * most significant byte positions.
141: */
142: blocksize = countbytes(N) - 1; /* Space available for data */
143: for (i = units2bytes(global_precision) - blocksize; i > 0; --i)
144: *p++ = 0;
145:
146: i = blocksize - 2 - bytes; /* Padding needed */
147: i -= sizeof(asn_array); /* Space for type encoding */
148: if (i < 0) {
149: i = -4; /* Error code */
150: goto Cleanup;
151: }
152: *p++ = MD_ENCRYPTED_BYTE; /* Type byte */
153: memset(p, ~0, i); /* All 1's padding */
154: p += i;
155: *p++ = 0; /* Zero framing byte */
156: memcpy(p, asn_array, sizeof(asn_array)); /* ASN data */
157: p += sizeof(asn_array);
158: memcpy(p, inbuf, bytes); /* User data */
159:
160: mp_convert_order((byte *)temp);
161: i = mp_modexp_crt(outbuf, temp, P, Q, DP, DQ, U); /* Encrypt */
162: if (i < 0)
163: i = -1;
164:
165: Cleanup:
166: burn(temp);
167:
168: return i;
169: } /* rsa_private_encrypt */
170:
171: /* Remove a signature packet from an MPI */
172: /* Thus, we expect constant padding and the MIC ASN sequence */
173: int
174: rsa_public_decrypt(byteptr outbuf, unitptr inbuf,
175: unitptr E, unitptr N)
176: /* Decrypt a message digest using a public key. Returns the number of bytes
177: * extracted, or <0 on error.
178: * -1: Corrupted packet.
179: * -3: Key too big
180: * -4: Key too small
181: * -5: Maybe malformed RSA packet
182: * -7: Unknown conventional algorithm
183: * -9: Malformed RSA packet
184: */
185: {
186: unit temp[MAX_UNIT_PRECISION];
187: unsigned int blocksize;
188: int i;
189: byte *front, *back;
190:
191: i = mp_modexp(temp, inbuf, E, N);
192: if (i < 0) {
193: mp_burn(temp);
194: return -1;
195: }
196: mp_convert_order((byte *)temp);
197: blocksize = countbytes(N) - 1;
198: front = (byte *)temp; /* Points to start of block */
199: i = units2bytes(global_precision);
200: back = front + i; /* Points to end of block */
201: i -= countbytes(N) - 1; /* Expected leading 0's */
202:
203: /*
204: * Strip off the padding. This handles both PKCS and PGP 2.0
205: * formats. If we're using RSAREF2, we use the padding-removal
206: * code in RSAPublicDecrypt, which accepts only PKCS style.
207: * Oh, well.
208: */
209:
210: if (i < 0) /* This shouldn't happen */
211: goto ErrorReturn;
212: while (i--) /* Extra bytes should be 0 */
213: if (*front++)
214: goto ErrorReturn;
215:
216: /* How to distinguish old PGP from PKCS formats.
217: * The old PGP format ends in a trailing type byte, with
218: * all 1's padding before that. The PKCS format ends in
219: * 16 bytes of message digest, preceded by an ASN string
220: * which is not all 1's.
221: */
222: if (back[-1] == MD_ENCRYPTED_BYTE &&
223: back[-17] == 0xff && back[-18] == 0xff) {
224: /* Old PGP format: Padding is at the end */
225: if (*--back != MD_ENCRYPTED_BYTE)
226: goto ErrorReturn;
227: if (*front++ != MD5_ALGORITHM_BYTE) {
228: mp_burn(temp);
229: return -7;
230: }
231: while (*--back == 0xff) /* Skip constant padding */
232: ;
233: if (*back) /* It should end with a zero */
234: goto ErrorReturn;
235: } else {
236: /* PKCS format: padding at the beginning */
237: if (*front++ != MD_ENCRYPTED_BYTE)
238: goto ErrorReturn;
239: while (*front++ == 0xff) /* Skip constant padding */
240: ;
241: if (front[-1]) /* First non-FF byte should be 0 */
242: goto ErrorReturn;
243: /* Then comes the ASN header */
244: if (memcmp(front, asn_array, sizeof(asn_array))) {
245: mp_burn(temp);
246: return -7;
247: }
248: front += sizeof(asn_array);
249: }
250:
251: /* We're done - copy user data to outbuf */
252: if (back < front)
253: goto ErrorReturn;
254: blocksize = back-front;
255: memcpy(outbuf, front, blocksize);
256: mp_burn(temp);
257: return blocksize;
258: ErrorReturn:
259: mp_burn(temp);
260: return -9;
261: } /* rsa_public_decrypt */
262:
263: /* We expect to find random padding and an encryption key */
264: int
265: rsa_private_decrypt(byteptr outbuf, unitptr inbuf,
266: unitptr E, unitptr D, unitptr P, unitptr Q, unitptr U, unitptr N)
267: /* Decrypt an encryption key using a private key. Returns the number of bytes
268: * extracted, or <0 on error.
269: * -1: Generic error
270: * -3: Key too big
271: * -4: Key too small
272: * -5: Maybe malformed RSA
273: * -7: Unknown conventional algorithm
274: * -9: Malformed RSA packet
275: */
276: {
277: byte *back;
278: byte *front;
279: unsigned int blocksize;
280: unit temp[MAX_UNIT_PRECISION];
281: unit DP[MAX_UNIT_PRECISION], DQ[MAX_UNIT_PRECISION];
282: int i;
283:
284: /* PGP doesn't store (d mod p-1) and (d mod q-1), so compute 'em */
285: mp_move(temp,P);
286: mp_dec(temp);
287: mp_mod(DP,D,temp);
288: mp_move(temp,Q);
289: mp_dec(temp);
290: mp_mod(DQ,D,temp);
291:
292: i = mp_modexp_crt(temp, inbuf, P, Q, DP, DQ, U);
293: mp_burn(DP);
294: mp_burn(DQ);
295: if (i < 0) {
296: mp_burn(temp);
297: return -1;
298: }
299: mp_convert_order((byte *)temp);
300: front = (byte *)temp; /* Start of block */
301: i = units2bytes(global_precision);
302: back = (byte *)front + i; /* End of block */
303: blocksize = countbytes(N) - 1;
304: i -= blocksize; /* Expected # of leading 0's */
305:
306: if (i < 0) /* This shouldn't happen */
307: goto Corrupted;
308: while (i--) /* Extra bytes should be 0 */
309: if (*front++)
310: goto Corrupted;
311:
312: /* How to distinguish old PGP from PKCS formats.
313: * PGP packets have a trailing type byte (CK_ENCRYPTED_BYTE),
314: * while PKCS formats have it leading.
315: */
316: if (front[0] != CK_ENCRYPTED_BYTE && back[-1] == CK_ENCRYPTED_BYTE) {
317: /* PGP 2.0 format - padding at the end */
318: if (back[-1] != CK_ENCRYPTED_BYTE)
319: goto Corrupted;
320: while (*--back) /* Skip non-zero random padding */
321: ;
322: } else {
323: /* PKCS format - padding at the beginning */
324: if (*front++ != CK_ENCRYPTED_BYTE)
325: goto Corrupted;
326: while (*front++) /* Skip non-zero random padding */
327: ;
328: }
329: if (back <= front)
330: goto Corrupted;
331: blocksize = back-front;
332:
333: memcpy(outbuf, front, blocksize);
334: mp_burn(temp);
335: return blocksize;
336:
337: Corrupted:
338: mp_burn(temp);
339: return -9;
340: } /* rsa_private_decrypt */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.