|
|
1.1 root 1: /* rsaglue.c - These functions wrap and unwrap message digests (MDs) and
2: * data encryption keys (DEKs) in padding and RSA-encrypt them into
3: * multi-precision integers. This layer was introduced to allow the
4: * transparent use of RSAREF for the encryption (in regions where it is
5: * legally available - the U.S. and treaty partners), or Philip Zimmermann's
6: * mpi library (where permitted by patent law - outside the U.S.).
7: *
8: * These functions also hide the details of using either PKCS or PGP 2.0
9: * style padding and encodings within the integers. See pgformat.doc
10: * for a detailed description of the formats.
11: */
12:
13: #include <string.h> /* for mem*() */
14: #include "mpilib.h"
15: #include "mpiio.h"
16: #include "pgp.h"
17: #include "rsaglue.h"
18:
19: #ifdef RSAREF /* defined (or not) in rsaglue.h */
20: #include "rsaref/test/global.h"
21: #include "rsaref/source/rsa.h"
22: #include "rsaref/source/rsaref.h"
23:
24: int RSAPublicBlock(byte *dest, unsigned *destbytesptr,
25: byte *src, unsigned srcbytes,
26: R_RSA_PUBLIC_KEY *PubKey);
27: int RSAPrivateBlock(byte *dest, unsigned *destbytesptr,
28: byte *src, unsigned srcbytes,
29: R_RSA_PRIVATE_KEY *PrivKey);
30:
31: /* Functions to convert to and from RSAREF's bignum formats */
32:
33: void
34: rsaref2reg (unitptr to, byte *from, int frombytes)
35: /* Convert an RSAREF-style MSB-first array of bytes to an mpi-style
36: * native-byte-order integer. (global_precision units long.)
37: */
38: {
39: int tobytes;
40:
41: tobytes = units2bytes (global_precision);
42: if (tobytes > frombytes) {
43: memset(to, 0, tobytes - frombytes);
44: memcpy((byte *)to + tobytes - frombytes, from, frombytes);
45: } else {
46: memcpy((byte *)to, from + frombytes - tobytes, tobytes);
47: }
48: #ifndef HIGHFIRST
49: hiloswap((byte *)to, tobytes);
50: #endif
51: } /* rsaref2reg */
52:
53: void
54: reg2rsaref (byte *to, int tobytes, unitptr from)
55: /* Convert the other way, mpi format to an array of bytes. */
56: {
57: int frombytes;
58:
59: frombytes = units2bytes(global_precision);
60:
61: #ifdef HIGHFIRST
62: if (tobytes > frombytes) {
63: memset(to, 0, tobytes-frombytes);
64: memcpy(to + tobytes - frombytes, (byte *)from, frombytes);
65: } else {
66: memcpy(to, (byte *)from + frombytes - tobytes, tobytes);
67: }
68: #else
69: if (tobytes > frombytes) {
70: memcpy(to, (byte *)from, frombytes);
71: memset(to + frombytes, 0, tobytes-frombytes);
72: } else {
73: memcpy(to, (byte *)from, tobytes);
74: }
75: hiloswap(to, tobytes);
76: #endif
77: } /* reg2rsaref */
78:
79: int
80: make_RSA_PUBLIC_KEY(R_RSA_PUBLIC_KEY *rpk, unitptr e, unitptr n)
81: /* Given mpi's e and n, fill in an R_RSA_PUBLIC_KEY structure.
82: * Returns -1 on error, 0 on success
83: */
84: {
85: rpk->bits = countbits(n);
86: if (rpk->bits > MAX_RSA_MODULUS_BITS)
87: return -1;
88:
89: reg2rsaref(rpk->modulus, MAX_RSA_MODULUS_LEN, n);
90: reg2rsaref(rpk->exponent, MAX_RSA_MODULUS_LEN, e);
91: return 0;
92: } /* make_RSA_PUBLIC_KEY */
93:
94: /* Returns -1 on error, 0 on success */
95: int
96: make_RSA_PRIVATE_KEY(R_RSA_PRIVATE_KEY *rpk, unitptr e, unitptr d, unitptr p,
97: unitptr q, unitptr dp, unitptr dq, unitptr u, unitptr n)
98: /* Given a number of necessary mpi's, fill in an R_RSA_PRIVATE_KEY structure.
99: * Returns -1 on error, 0 on success
100: */
101: {
102: rpk->bits = countbits(n);
103: if (rpk->bits > MAX_RSA_MODULUS_BITS ||
104: countbits(p) > MAX_RSA_PRIME_BITS ||
105: countbits(q) > MAX_RSA_PRIME_BITS)
106: return -1;
107:
108: reg2rsaref(rpk->modulus, MAX_RSA_MODULUS_LEN, n);
109: reg2rsaref(rpk->publicExponent, MAX_RSA_MODULUS_LEN, e);
110: reg2rsaref(rpk->exponent, MAX_RSA_MODULUS_LEN, d);
111: /* The larger prime (p) first */
112: reg2rsaref(rpk->prime[0], MAX_RSA_PRIME_LEN, q);
113: reg2rsaref(rpk->prime[1], MAX_RSA_PRIME_LEN, p);
114: /* d mod (p-1) and d mod (q-1) */
115: reg2rsaref(rpk->primeExponent[0], MAX_RSA_PRIME_LEN, dq);
116: reg2rsaref(rpk->primeExponent[1], MAX_RSA_PRIME_LEN, dp);
117: /* 1/q mod p */
118: reg2rsaref(rpk->coefficient, MAX_RSA_PRIME_LEN, u);
119: return 0;
120: } /* make_RSA_PRIVATE_KEY */
121:
122: #endif /* RSAREF */
123:
124: /* These functions hide all the internal details of RSA-encrypted
125: * keys and digests. They owe a lot of their heritage to
126: * the preblock() and postunblock() routines in mpiio.c.
127: */
128:
129: /* Abstract Syntax Notation One (ASN.1) Distinguished Encoding Rules (DER)
130: encoding for RSA/MD5, used in PKCS-format signatures. */
131: static byte asn_array[] = { /* PKCS 01 block type 01 data */
132: 0x30,0x20,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
133: 0x02,0x05,0x05,0x00,0x04,0x10 };
134: /* This many bytes from the end, there's a zero byte */
135: #define ASN_ZERO_END 3
136:
137: int
138: rsa_public_encrypt(unitptr outbuf, byteptr inbuf, short bytes,
139: unitptr E, unitptr N)
140: /* Encrypt a DEK with a public key. Returns 0 on success.
141: * <0 means there was an error
142: */
143: {
144: unit temp[MAX_UNIT_PRECISION];
145: #ifdef RSAREF
146: R_RSA_PUBLIC_KEY PubKey;
147: R_RANDOM_STRUCT Random;
148: #endif /* RSAREF */
149: unsigned int blocksize;
150: byte *p;
151: int i; /* Temporary, and holds error codes */
152:
153: blocksize = countbytes(N) - 1; /* Bytes available for user data */
154:
155: p = (byte *)temp;
156:
157: #ifdef RSAREF
158: /* Fill in the R_RSA_PUBLIC_KEY structure as needed later. */
159: i = make_RSA_PUBLIC_KEY(&PubKey, E, N);
160: if (i < 0)
161: return -1;
162: #else /* !RSAREF */
163: /* If !RSAREF, we are building the mpi in place, except for a
164: * possible byte-order swap to little-endian at the end. Thus,
165: * we need to fill the buffer with leading 0's in the unused
166: * most significant byte positions.
167: */
168: for (i = units2bytes(global_precision) - blocksize; i > 0; --i)
169: *p++ = 0;
170: #endif /* !RSAREF */
171:
172: /* Both the PKCS and PGP 2.0 key formats add a type byte, and a
173: * a framing byte of 0 to the user data. The remaining space
174: * is filled with random padding. (PKCS requires that there be
175: * at least 1 byte of padding.)
176: */
177: i = blocksize - 2 - bytes;
178:
179: if (pkcs_compat) {
180: if (i < 1) /* Less than minimum padding? */
181: return -1;
182: #ifndef RSAREF /* Build the packet ourselves */
183: *p++ = CK_ENCRYPTED_BYTE; /* Type byte */
184: while (i) /* Non-zero random padding */
185: if ((*p = idearand()))
186: ++p, --i;
187: *p++ = 0; /* Framing byte */
188: memcpy(p, inbuf, bytes); /* User data */
189: #else /* RSAREF */
190: /* The RSAREF routines have their own random number generator
191: * to generate random padding. The following code seeds it
192: * from PGP's random number generator.
193: */
194: R_RandomInit(&Random);
195: for (;;) {
196: R_GetRandomBytesNeeded(&i, &Random);
197: if (i <= 0)
198: break;
199: blocksize = i > sizeof(temp) ? sizeof(temp) : i;
200: for (i = 0; i < blocksize; i++)
201: ((byte *)temp)[i] = idearand();
202: R_RandomUpdate(&Random, (byte *)temp, blocksize);
203: }
204: /* Pad and encrypt */
205: i = RSAPublicEncrypt((byte *)temp, &blocksize,
206: inbuf, bytes, &PubKey, &Random);
207: R_RandomFinal(&Random); /* Clean up RSAREF's RNG */
208: burn(Random); /* Just to be sure */
209: #endif /* RSAREF */
210: } else { /* !pkcs_compat */
211: if (i < 0)
212: return -1;
213: memcpy(p, inbuf, bytes); /* User data */
214: p += bytes;
215: *p++ = 0; /* Framing byte */
216: while (i) /* Non-zero random padding */
217: if ((*p = idearand()))
218: ++p, --i;
219: *p = CK_ENCRYPTED_BYTE; /* Type byte */
220: #ifdef RSAREF
221: /* Do the encryption */
222: i = RSAPublicBlock((byte *)temp, &blocksize,
223: (byte *)temp, blocksize, &PubKey);
224: #endif
225:
226: } /* !pkcs_compat */
227:
228: #ifndef RSAREF
229: mp_convert_order((byte *)temp); /* Convert buffer to MPI */
230: i = mp_modexp(outbuf, temp, E, N); /* Do the encryption */
231: #else /* RSAREF */
232: rsaref2reg(outbuf, (byte *)temp, blocksize);
233: #endif /* RSAREF */
234:
235: Cleanup:
236: mp_burn(temp);
237: #ifdef RSAREF
238: burn(PubKey);
239: #endif
240: return i < 0 ? i : 0;
241: } /* rsa_public_encrypt */
242:
243: int
244: rsa_private_encrypt(unitptr outbuf, byteptr inbuf, short bytes,
245: unitptr E, unitptr D, unitptr P, unitptr Q, unitptr U, unitptr N)
246: /* Encrypt a message digest with a private key.
247: * Returns <0 on error.
248: */
249: {
250: unit temp[MAX_UNIT_PRECISION];
251: unit DP[MAX_UNIT_PRECISION], DQ[MAX_UNIT_PRECISION];
252: #ifdef RSAREF
253: R_RSA_PRIVATE_KEY PrivKey;
254: #else
255: int byte_precision;
256: #endif
257: unsigned int blocksize;
258: byte *p;
259: int i;
260:
261: /* PGP doesn't store these coefficents, so we need to compute them. */
262: mp_move(temp,P);
263: mp_dec(temp);
264: mp_mod(DP,D,temp);
265: mp_move(temp,Q);
266: mp_dec(temp);
267: mp_mod(DQ,D,temp);
268:
269: blocksize = countbytes(N) - 1; /* Space available for data */
270:
271: p = (byte *)temp;
272:
273: #ifdef RSAREF
274: i = make_RSA_PRIVATE_KEY(&PrivKey, E, D, P, Q, DP, DQ, U, N);
275: if (i < 0)
276: goto Cleanup;
277: #else
278: /* If !RSAREF, we are building the mpi in place, except for a
279: * possible byte-order swap to little-endian at the end. Thus,
280: * we need to fill the buffer with leading 0's in the unused
281: * most significant byte positions.
282: */
283: for (i = units2bytes(global_precision) - blocksize; i > 0; --i)
284: *p++ = 0;
285: #endif
286: i = blocksize - 2 - bytes; /* Padding needed */
287:
288: if (pkcs_compat) {
289: #ifndef RSAREF /* Pad the packet ourselves */
290: i -= sizeof(asn_array); /* Space for type encoding */
291: if (i < 0) {
292: i = -1; /* Error code */
293: goto Cleanup;
294: }
295: *p++ = MD_ENCRYPTED_BYTE; /* Type byte */
296: memset(p, ~0, i); /* All 1's padding */
297: p += i;
298: *p++ = 0; /* Zero framing byte */
299: #endif /* !RSAREF */
300: memcpy(p, asn_array, sizeof(asn_array)); /* ASN data */
301: p += sizeof(asn_array);
302: memcpy(p, inbuf, bytes); /* User data */
303: #ifdef RSAREF
304: /* Pad and encrypt */
305: RSAPrivateEncrypt((byte *)temp, &blocksize,
306: (byte *)temp, bytes+sizeof(asn_array),
307: &PrivKey);
308: #endif
309: } else { /* Not pkcs_compat */
310: --i; /* Space for type byte */
311: if (i < 0) {
312: i = -1; /* Error code */
313: goto Cleanup;
314: }
315: *p++ = MD5_ALGORITHM_BYTE; /* Algorithm type byte */
316: memcpy(p, inbuf, bytes); /* User data */
317: p += bytes;
318: *p++ = 0; /* Framing byte of 0 */
319: memset(p, ~0, i); /* All 1's padding */
320: p += i;
321: *p = MD_ENCRYPTED_BYTE; /* Type byte */
322:
323: #ifdef RSAREF
324: /* Do the encryption */
325: i = RSAPrivateBlock((byte *)temp, &blocksize,
326: (byte *)temp, blocksize, &PrivKey);
327: #endif /* RSAREF */
328:
329: } /* !pkcs_compat */
330:
331: #ifndef RSAREF
332: mp_convert_order((byte *)temp);
333: i = mp_modexp_crt(outbuf, temp, P, Q, DP, DQ, U); /* Encrypt */
334: #else /* RSAREF */
335: rsaref2reg(outbuf, (byte *)temp, blocksize);
336: #endif /* RSAREF */
337:
338: Cleanup:
339: mp_burn(temp);
340: #ifdef RSAREF
341: memset(&PrivKey, 0, sizeof(PrivKey));
342: #endif
343: return i < 0 ? i : 0;
344: } /* rsa_private_encrypt */
345:
346: /* Remove a signature packet from an MPI */
347: /* Thus, we expect constant padding and the MIC ASN sequence */
348: int
349: rsa_public_decrypt(byteptr outbuf, unitptr inbuf,
350: unitptr E, unitptr N)
351: /* Decrypt a message digest using a public key. Returns the number of bytes
352: * extracted, or <0 on error.
353: * -1: Corrupted packet.
354: * -2: Unrecognized message digest algorithm.
355: */
356: {
357: #ifdef RSAREF
358: R_RSA_PUBLIC_KEY PubKey;
359: #endif
360: unit temp[MAX_UNIT_PRECISION];
361: unsigned int blocksize;
362: int i;
363: byte *front, *back;
364:
365: #ifdef RSAREF
366: make_RSA_PUBLIC_KEY(&PubKey, E, N);
367: blocksize = countbytes(inbuf);
368: reg2rsaref((byte *)temp, blocksize, inbuf);
369: RSAPublicBlock((byte *)temp, &blocksize,
370: (byte *)temp, blocksize, &PubKey);
371:
372: front = (byte *)temp; /* The start of the block */
373: back = front + blocksize; /* The end */
374: i = blocksize - countbytes(N) + 1; /* Expected leading 0's */
375: #else
376: i = mp_modexp(temp, inbuf, E, N);
377: if (i < 0) {
378: mp_burn(temp);
379: return i;
380: }
381: mp_convert_order((byte *)temp);
382: blocksize = countbytes(N) - 1;
383: front = (byte *)temp; /* Points to start of block */
384: i = units2bytes(global_precision);
385: back = front + i; /* Points to end of block */
386: i -= countbytes(N) - 1; /* Expected leading 0's */
387: #endif
388:
389: /* This could be stricter, but the length returned by the RSAREF code
390: is not documented too well. */
391: if (i < 0)
392: goto ErrorReturn;
393: while (i--) /* Any excess should be 0 */
394: if (*front++)
395: goto ErrorReturn;
396: /* front now points to the data */
397:
398: /* How to distinguish old PGP from PKCS formats.
399: * The old PGP format ends in a trailing type byte, with
400: * all 1's padding before that. The PKCS format ends in
401: * 16 bytes of message digest, preceded by an ASN string
402: * which is not all 1's.
403: */
404: if (back[-1] == MD_ENCRYPTED_BYTE &&
405: back[-17] == 0xff && back[-18] == 0xff) {
406: /* Old PGP format: Padding is at the end */
407: if (*--back != MD_ENCRYPTED_BYTE)
408: goto ErrorReturn;
409: if (*front++ != MD5_ALGORITHM_BYTE) {
410: mp_burn(temp);
411: return -2;
412: }
413: while (*--back == 0xff) /* Skip constant padding */
414: ;
415: if (*back) /* It should end with a zero */
416: goto ErrorReturn;
417: } else {
418: /* PKCS format: padding at the beginning */
419: if (*front++ != MD_ENCRYPTED_BYTE)
420: goto ErrorReturn;
421: while (*front++ == 0xff) /* Skip constant padding */
422: ;
423: if (front[-1]) /* First non-FF byte should be 0 */
424: goto ErrorReturn;
425: /* Then comes the ASN header */
426: if (memcmp(front, asn_array, sizeof(asn_array))) {
427: mp_burn(temp);
428: return -2;
429: }
430: front += sizeof(asn_array);
431: /* This is temporary - to be removed on release */
432: if (back-front == 17 && *front == MD5_ALGORITHM_BYTE) {
433: front++;
434: fprintf(stderr, "PGP 2.2b signature bug!\n");
435: }
436: }
437: /* We're done - copy user data to outbuf */
438: if (back < front)
439: goto ErrorReturn;
440: memcpy(outbuf, front, back-front);
441: mp_burn(temp);
442: return back-front;
443: ErrorReturn:
444: mp_burn(temp);
445: return -1;
446: } /* rsa_public_decrypt */
447:
448: /* We expect to find random padding and an encryption key */
449: int
450: rsa_private_decrypt(byteptr outbuf, unitptr inbuf,
451: unitptr E, unitptr D, unitptr P, unitptr Q, unitptr U, unitptr N)
452: /* Decrypt an encryption key using a private key. Returns the number of bytes
453: * extracted, or <0 on error.
454: * -1: Corrupted packet.
455: */
456: {
457: #ifdef RSAREF
458: R_RSA_PRIVATE_KEY PrivKey;
459: #endif
460: unsigned int blocksize;
461: unit temp[MAX_UNIT_PRECISION];
462: unit DP[MAX_UNIT_PRECISION], DQ[MAX_UNIT_PRECISION];
463: byte *front, *back;
464: int i;
465:
466: mp_move(temp,P);
467: mp_dec(temp);
468: mp_mod(DP,D,temp);
469: mp_move(temp,Q);
470: mp_dec(temp);
471: mp_mod(DQ,D,temp);
472:
473: #ifdef RSAREF
474: make_RSA_PRIVATE_KEY(&PrivKey, E, D, P, Q, DP, DQ, U, N);
475: blocksize = countbytes(inbuf);
476: reg2rsaref((byte *)temp, blocksize, inbuf);
477: i = RSAPrivateBlock((byte *)temp, &blocksize,
478: (byte *)temp, blocksize, &PrivKey);
479: if (i < 0)
480: goto ErrorReturn;
481: front = (byte *)temp; /* Start of block */
482: back = front + blocksize; /* End of block */
483: i = blocksize - countbytes(N) + 1; /* Expected # of leading 0's */
484: #else
485: i = mp_modexp_crt(temp, inbuf, P, Q, DP, DQ, U);
486: if (i < 0)
487: goto ErrorReturn;
488: mp_convert_order((byte *)temp);
489: front = (byte *)temp; /* Start of block */
490: i = units2bytes(global_precision);
491: back = (byte *)front + i; /* End of block */
492: blocksize = countbytes(N) - 1;
493: i -= blocksize; /* Expected # of leading 0's */
494: #endif
495: if (i < 0) /* This shouldn't happen */
496: goto ErrorReturn;
497: while (i--) /* Extra bytes should be 0 */
498: if (*front++)
499: goto ErrorReturn;
500:
501: /* How to distinguish old PGP from PKCS formats.
502: * PGP packets have a trailing type byte (CK_ENCRYPTED_BYTE),
503: * while PKCS formats have it leading.
504: */
505: if (front[0] != CK_ENCRYPTED_BYTE && back[-1] == CK_ENCRYPTED_BYTE) {
506: /* PGP 2.0 format - padding at the end */
507: if (back[-1] != CK_ENCRYPTED_BYTE)
508: goto ErrorReturn;
509: while (*--back) /* Skip non-zero random padding */
510: ;
511: } else {
512: /* PKCS format - padding at the beginning */
513: if (*front++ != CK_ENCRYPTED_BYTE)
514: goto ErrorReturn;
515: while (*front++) /* Skip non-zero random padding */
516: ;
517: }
518: if (back < front)
519: goto ErrorReturn;
520: memcpy(outbuf, front, back-front);
521: mp_burn(temp);
522: mp_burn(DP);
523: mp_burn(DQ);
524: return back-front;
525:
526: ErrorReturn:
527: mp_burn(temp);
528: mp_burn(DP);
529: mp_burn(DQ);
530: return -1;
531: } /* rsa_private_decrypt */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.