|
|
1.1 root 1: /* R_ENHANC.C - cryptographic enhancements for RSAREF
2: */
3:
4: /* Copyright (C) RSA Laboratories, a division of RSA Data Security,
5: Inc., created 1991. All rights reserved.
6: */
7:
8: #include "global.h"
9: #include "rsaref.h"
10: #include "r_random.h"
11: #include "rsa.h"
12:
13: /* DigestInfo encoding is DIGEST_INFO_A, then 2 or 5 (for MD2/MD5),
14: then DIGEST_INFO_B, then 16-byte message digest.
15: */
16:
17: static unsigned char DIGEST_INFO_A[] = {
18: 0x30, 0x20, 0x30, 0x0c, 0x06, 0x08, 0x2a, 0x86, 0x48, 0x86, 0xf7,
19: 0x0d, 0x02
20: };
21: #define DIGEST_INFO_A_LEN sizeof (DIGEST_INFO_A)
22:
23: static unsigned char DIGEST_INFO_B[] = { 0x05, 0x00, 0x04, 0x10 };
24: #define DIGEST_INFO_B_LEN sizeof (DIGEST_INFO_B)
25:
26: #define DIGEST_INFO_LEN (DIGEST_INFO_A_LEN + 1 + DIGEST_INFO_B_LEN + 16)
27:
28: static unsigned char *PADDING[] = {
29: (unsigned char *)"", (unsigned char *)"\001", (unsigned char *)"\002\002",
30: (unsigned char *)"\003\003\003", (unsigned char *)"\004\004\004\004",
31: (unsigned char *)"\005\005\005\005\005",
32: (unsigned char *)"\006\006\006\006\006\006",
33: (unsigned char *)"\007\007\007\007\007\007\007",
34: (unsigned char *)"\010\010\010\010\010\010\010\010"
35: };
36:
37: #define MAX_ENCRYPTED_KEY_LEN MAX_RSA_MODULUS_LEN
38:
39: static void R_EncodeDigestInfo PROTO_LIST
40: ((unsigned char *, int, unsigned char *));
41: static void EncryptPEMUpdateFinal PROTO_LIST
42: ((R_ENVELOPE_CTX *, unsigned char *, unsigned int *, unsigned char *,
43: unsigned int));
44: static int DecryptPEMUpdateFinal PROTO_LIST
45: ((R_ENVELOPE_CTX *, unsigned char *, unsigned int *, unsigned char *,
46: unsigned int));
47: static int CipherInit PROTO_LIST
48: ((R_ENVELOPE_CTX *, int, unsigned char *, unsigned char *, int));
49: static void CipherUpdate PROTO_LIST
50: ((R_ENVELOPE_CTX *, unsigned char *, unsigned char *, unsigned int));
51: static void CipherRestart PROTO_LIST ((R_ENVELOPE_CTX *));
52:
53: int R_DigestInit (context, digestAlgorithm)
54: R_DIGEST_CTX *context; /* new context */
55: int digestAlgorithm; /* message-digest algorithm */
56: {
57: context->digestAlgorithm = digestAlgorithm;
58:
59: switch (digestAlgorithm) {
60: case DA_MD2:
61: MD2Init (&context->context.md2);
62: break;
63:
64: case DA_MD5:
65: MD5Init (&context->context.md5);
66: break;
67:
68: default:
69: return (RE_DIGEST_ALGORITHM);
70: }
71:
72: return (0);
73: }
74:
75: int R_DigestUpdate (context, partIn, partInLen)
76: R_DIGEST_CTX *context; /* context */
77: unsigned char *partIn; /* next data part */
78: unsigned int partInLen; /* length of next data part */
79: {
80: if (context->digestAlgorithm == DA_MD2)
81: MD2Update (&context->context.md2, partIn, partInLen);
82: else
83: MD5Update (&context->context.md5, partIn, partInLen);
84: return (0);
85: }
86:
87: int R_DigestFinal (context, digest, digestLen)
88: R_DIGEST_CTX *context; /* context */
89: unsigned char *digest; /* message digest */
90: unsigned int *digestLen; /* length of message digest */
91: {
92: *digestLen = 16;
93: if (context->digestAlgorithm == DA_MD2)
94: MD2Final (digest, &context->context.md2);
95: else
96: MD5Final (digest, &context->context.md5);
97:
98: return (0);
99: }
100:
101: int R_SignInit (context, digestAlgorithm)
102: R_SIGNATURE_CTX *context; /* new context */
103: int digestAlgorithm; /* message-digest algorithm */
104: {
105: return (R_DigestInit (&context->digestContext, digestAlgorithm));
106: }
107:
108: int R_SignUpdate (context, partIn, partInLen)
109: R_SIGNATURE_CTX *context; /* context */
110: unsigned char *partIn; /* next data part */
111: unsigned int partInLen; /* length of next data part */
112: {
113: return (R_DigestUpdate (&context->digestContext, partIn, partInLen));
114: }
115:
116: int R_SignFinal (context, signature, signatureLen, privateKey)
117: R_SIGNATURE_CTX *context; /* context */
118: unsigned char *signature; /* signature */
119: unsigned int *signatureLen; /* length of signature */
120: R_RSA_PRIVATE_KEY *privateKey; /* signer's RSA private key */
121: {
122: int status;
123: unsigned char digest[MAX_DIGEST_LEN], digestInfo[DIGEST_INFO_LEN];
124: unsigned int digestLen;
125:
126: do {
127: if ((status = R_DigestFinal (&context->digestContext, digest, &digestLen))
128: != 0)
129: break;
130:
131: R_EncodeDigestInfo
132: (digestInfo, context->digestContext.digestAlgorithm, digest);
133:
134: if (RSAPrivateEncrypt
135: (signature, signatureLen, digestInfo, DIGEST_INFO_LEN, privateKey)
136: != 0) {
137: status = RE_PRIVATE_KEY;
138: break;
139: }
140:
141: /* Reset for another verification. Assume Init won't fail */
142: R_DigestInit
143: (&context->digestContext, context->digestContext.digestAlgorithm);
144: } while (0);
145:
146: /* Zeroize potentially sensitive information.
147: */
148: R_memset ((POINTER)digest, 0, sizeof (digest));
149: R_memset ((POINTER)digestInfo, 0, sizeof (digestInfo));
150:
151: return (status);
152: }
153:
154: int R_VerifyInit (context, digestAlgorithm)
155: R_SIGNATURE_CTX *context; /* new context */
156: int digestAlgorithm; /* message-digest algorithm */
157: {
158: return (R_DigestInit (&context->digestContext, digestAlgorithm));
159: }
160:
161: int R_VerifyUpdate (context, partIn, partInLen)
162: R_SIGNATURE_CTX *context; /* context */
163: unsigned char *partIn; /* next data part */
164: unsigned int partInLen; /* length of next data part */
165: {
166: return (R_DigestUpdate (&context->digestContext, partIn, partInLen));
167: }
168:
169: int R_VerifyFinal (context, signature, signatureLen, publicKey)
170: R_SIGNATURE_CTX *context; /* context */
171: unsigned char *signature; /* signature */
172: unsigned int signatureLen; /* length of signature */
173: R_RSA_PUBLIC_KEY *publicKey; /* signer's RSA public key */
174: {
175: int status;
176: unsigned char digest[MAX_DIGEST_LEN], digestInfo[DIGEST_INFO_LEN],
177: originalDigestInfo[MAX_SIGNATURE_LEN];
178: unsigned int originalDigestInfoLen, digestLen;
179:
180: if (signatureLen > MAX_SIGNATURE_LEN)
181: return (RE_LEN);
182:
183: status = 0;
184: do {
185: if ((status = R_DigestFinal (&context->digestContext, digest, &digestLen))
186: != 0)
187: break;
188:
189: R_EncodeDigestInfo
190: (digestInfo, context->digestContext.digestAlgorithm, digest);
191:
192: if (RSAPublicDecrypt
193: (originalDigestInfo, &originalDigestInfoLen, signature, signatureLen,
194: publicKey) != 0) {
195: status = RE_PUBLIC_KEY;
196: break;
197: }
198:
199: if ((originalDigestInfoLen != DIGEST_INFO_LEN) ||
200: (R_memcmp
201: ((POINTER)originalDigestInfo, (POINTER)digestInfo,
202: DIGEST_INFO_LEN))) {
203: status = RE_SIGNATURE;
204: break;
205: }
206:
207: /* Reset for another verification. Assume Init won't fail */
208: R_DigestInit
209: (&context->digestContext, context->digestContext.digestAlgorithm);
210: } while (0);
211:
212: /* Zeroize potentially sensitive information.
213: */
214: R_memset ((POINTER)digest, 0, sizeof (digest));
215: R_memset ((POINTER)digestInfo, 0, sizeof (digestInfo));
216: R_memset ((POINTER)originalDigestInfo, 0, sizeof (originalDigestInfo));
217:
218: return (status);
219: }
220:
221: /* Caller must ASCII recode the encrypted keys if desired.
222: */
223: int R_SealInit
224: (context, encryptedKeys, encryptedKeyLens, iv, publicKeyCount, publicKeys,
225: encryptionAlgorithm, randomStruct)
226: R_ENVELOPE_CTX *context; /* new context */
227: unsigned char **encryptedKeys; /* encrypted keys */
228: unsigned int *encryptedKeyLens; /* lengths of encrypted keys */
229: unsigned char iv[8]; /* initialization vector */
230: unsigned int publicKeyCount; /* number of public keys */
231: R_RSA_PUBLIC_KEY **publicKeys; /* public keys */
232: int encryptionAlgorithm; /* data encryption algorithm */
233: R_RANDOM_STRUCT *randomStruct; /* random structure */
234: {
235: int status;
236: unsigned char key[24];
237: unsigned int keyLen, i;
238:
239: do {
240: context->encryptionAlgorithm = encryptionAlgorithm;
241:
242: keyLen = (encryptionAlgorithm == EA_DES_CBC) ? 8 : 24;
243: if ((status = R_GenerateBytes (key, keyLen, randomStruct)) != 0)
244: break;
245: if ((status = R_GenerateBytes (iv, 8, randomStruct)) != 0)
246: break;
247:
248: if (encryptionAlgorithm == EA_DES_EDE2_CBC)
249: /* Make both E keys the same */
250: R_memcpy ((POINTER)(key + 16), (POINTER)key, 8);
251:
252: if ((status = CipherInit (context, encryptionAlgorithm, key, iv, 1)) != 0)
253: break;
254:
255: for (i = 0; i < publicKeyCount; ++i) {
256: if (RSAPublicEncrypt
257: (encryptedKeys[i], &encryptedKeyLens[i], key, keyLen,
258: publicKeys[i], randomStruct)) {
259: status = RE_PUBLIC_KEY;
260: break;
261: }
262: }
263: if (status != 0)
264: break;
265:
266: context->bufferLen = 0;
267: } while (0);
268:
269: /* Zeroize sensitive information.
270: */
271: R_memset ((POINTER)key, 0, sizeof (key));
272:
273: return (status);
274: }
275:
276: /* Assume partOut buffer is at least partInLen + 7, since this may flush
277: buffered input.
278: */
279: int R_SealUpdate (context, partOut, partOutLen, partIn, partInLen)
280: R_ENVELOPE_CTX *context; /* context */
281: unsigned char *partOut; /* next encrypted data part */
282: unsigned int *partOutLen; /* length of next encrypted data part */
283: unsigned char *partIn; /* next data part */
284: unsigned int partInLen; /* length of next data part */
285: {
286: unsigned int tempLen;
287:
288: tempLen = 8 - context->bufferLen;
289: if (partInLen < tempLen) {
290: /* Just accumulate into buffer.
291: */
292: R_memcpy
293: ((POINTER)(context->buffer + context->bufferLen), (POINTER)partIn,
294: partInLen);
295: context->bufferLen += partInLen;
296: *partOutLen = 0;
297: return (0);
298: }
299:
300: /* Fill the buffer and encrypt.
301: */
302: R_memcpy
303: ((POINTER)(context->buffer + context->bufferLen), (POINTER)partIn,
304: tempLen);
305: CipherUpdate (context, partOut, context->buffer, 8);
306: partIn += tempLen;
307: partInLen -= tempLen;
308: partOut += 8;
309: *partOutLen = 8;
310:
311: /* Encrypt as many 8-byte blocks as possible.
312: */
313: tempLen = 8 * (partInLen / 8);
314: CipherUpdate (context, partOut, partIn, tempLen);
315: partIn += tempLen;
316: partInLen -= tempLen;
317: *partOutLen += tempLen;
318:
319: /* Length is now less than 8, so copy remainder to buffer.
320: */
321: R_memcpy
322: ((POINTER)context->buffer, (POINTER)partIn,
323: context->bufferLen = partInLen);
324:
325: return (0);
326: }
327:
328: /* Assume partOut buffer is at least 8 bytes.
329: */
330: int R_SealFinal (context, partOut, partOutLen)
331: R_ENVELOPE_CTX *context; /* context */
332: unsigned char *partOut; /* last encrypted data part */
333: unsigned int *partOutLen; /* length of last encrypted data part */
334: {
335: unsigned int padLen;
336:
337: /* Pad and encrypt final block.
338: */
339: padLen = 8 - context->bufferLen;
340: R_memset
341: ((POINTER)(context->buffer + context->bufferLen), (int)padLen, padLen);
342: CipherUpdate (context, partOut, context->buffer, 8);
343: *partOutLen = 8;
344:
345: /* Restart the context.
346: */
347: CipherRestart (context);
348: context->bufferLen = 0;
349:
350: return (0);
351: }
352:
353: /* Assume caller has already ASCII decoded the encryptedKey if necessary.
354: */
355: int R_OpenInit
356: (context, encryptionAlgorithm, encryptedKey, encryptedKeyLen, iv, privateKey)
357: R_ENVELOPE_CTX *context; /* new context */
358: int encryptionAlgorithm; /* data encryption algorithm */
359: unsigned char *encryptedKey; /* encrypted data encryption key */
360: unsigned int encryptedKeyLen; /* length of encrypted key */
361: unsigned char iv[8]; /* initialization vector */
362: R_RSA_PRIVATE_KEY *privateKey; /* recipient's RSA private key */
363: {
364: int status;
365: unsigned char key[MAX_ENCRYPTED_KEY_LEN];
366: unsigned int keyLen;
367:
368: if (encryptedKeyLen > MAX_ENCRYPTED_KEY_LEN)
369: return (RE_LEN);
370:
371: do {
372: context->encryptionAlgorithm = encryptionAlgorithm;
373:
374: if (RSAPrivateDecrypt
375: (key, &keyLen, encryptedKey, encryptedKeyLen, privateKey)) {
376: status = RE_PRIVATE_KEY;
377: break;
378: }
379:
380: if (encryptionAlgorithm == EA_DES_CBC) {
381: if (keyLen != 8) {
382: status = RE_PRIVATE_KEY;
383: break;
384: }
385: }
386: else {
387: if (keyLen != 24) {
388: status = RE_PRIVATE_KEY;
389: break;
390: }
391: }
392:
393: if ((status = CipherInit (context, encryptionAlgorithm, key, iv, 0)) != 0)
394: break;
395:
396: context->bufferLen = 0;
397: } while (0);
398:
399: /* Zeroize sensitive information.
400: */
401: R_memset ((POINTER)key, 0, sizeof (key));
402:
403: return (status);
404: }
405:
406: /* Assume partOut buffer is at least partInLen + 7, since this may flush
407: buffered input. Always leaves at least one byte in buffer.
408: */
409: int R_OpenUpdate (context, partOut, partOutLen, partIn, partInLen)
410: R_ENVELOPE_CTX *context; /* context */
411: unsigned char *partOut; /* next recovered data part */
412: unsigned int *partOutLen; /* length of next recovered data part */
413: unsigned char *partIn; /* next encrypted data part */
414: unsigned int partInLen; /* length of next encrypted data part */
415: {
416: unsigned int tempLen;
417:
418: tempLen = 8 - context->bufferLen;
419: if (partInLen <= tempLen) {
420: /* Just accumulate into buffer.
421: */
422: R_memcpy
423: ((POINTER)(context->buffer + context->bufferLen), (POINTER)partIn,
424: partInLen);
425: context->bufferLen += partInLen;
426: *partOutLen = 0;
427: return (0);
428: }
429:
430: /* Fill the buffer and decrypt. We know that there will be more left
431: in partIn after decrypting the buffer.
432: */
433: R_memcpy
434: ((POINTER)(context->buffer + context->bufferLen), (POINTER)partIn,
435: tempLen);
436: CipherUpdate (context, partOut, context->buffer, 8);
437: partIn += tempLen;
438: partInLen -= tempLen;
439: partOut += 8;
440: *partOutLen = 8;
441:
442: /* Decrypt as many 8 byte blocks as possible, leaving at least one byte
443: in partIn.
444: */
445: tempLen = 8 * ((partInLen - 1) / 8);
446: CipherUpdate (context, partOut, partIn, tempLen);
447: partIn += tempLen;
448: partInLen -= tempLen;
449: *partOutLen += tempLen;
450:
451: /* Length is between 1 and 8, so copy into buffer.
452: */
453: R_memcpy
454: ((POINTER)context->buffer, (POINTER)partIn,
455: context->bufferLen = partInLen);
456:
457: return (0);
458: }
459:
460: /* Assume partOut buffer is at least 7 bytes.
461: */
462: int R_OpenFinal (context, partOut, partOutLen)
463: R_ENVELOPE_CTX *context; /* context */
464: unsigned char *partOut; /* last recovered data part */
465: unsigned int *partOutLen; /* length of last recovered data part */
466: {
467: int status;
468: unsigned char lastPart[8];
469: unsigned int padLen;
470:
471: status = 0;
472: do {
473: if (context->bufferLen == 0)
474: /* There was no input data to decrypt */
475: *partOutLen = 0;
476: else {
477: if (context->bufferLen != 8) {
478: status = RE_KEY;
479: break;
480: }
481:
482: /* Decrypt and strip padding from final block which is in buffer.
483: */
484: CipherUpdate (context, lastPart, context->buffer, 8);
485:
486: padLen = lastPart[7];
487: if (padLen == 0 || padLen > 8) {
488: status = RE_KEY;
489: break;
490: }
491: if (R_memcmp
492: ((POINTER)&lastPart[8 - padLen], PADDING[padLen], padLen) != 0) {
493: status = RE_KEY;
494: break;
495: }
496:
497: R_memcpy ((POINTER)partOut, (POINTER)lastPart, *partOutLen = 8 - padLen);
498: }
499:
500: /* Restart the context.
501: */
502: CipherRestart (context);
503: context->bufferLen = 0;
504: } while (0);
505:
506: /* Zeroize sensitive information.
507: */
508: R_memset ((POINTER)lastPart, 0, sizeof (lastPart));
509:
510: return (status);
511: }
512:
513: int R_SignPEMBlock
514: (encodedContent, encodedContentLen, encodedSignature, encodedSignatureLen,
515: content, contentLen, recode, digestAlgorithm, privateKey)
516: unsigned char *encodedContent; /* encoded content */
517: unsigned int *encodedContentLen; /* length of encoded content */
518: unsigned char *encodedSignature; /* encoded signature */
519: unsigned int *encodedSignatureLen; /* length of encoded signature */
520: unsigned char *content; /* content */
521: unsigned int contentLen; /* length of content */
522: int recode; /* recoding flag */
523: int digestAlgorithm; /* message-digest algorithm */
524: R_RSA_PRIVATE_KEY *privateKey; /* signer's RSA private key */
525: {
526: int status;
527: unsigned char signature[MAX_SIGNATURE_LEN];
528: unsigned int signatureLen;
529:
530: if ((status = R_SignBlock
531: (signature, &signatureLen, content, contentLen, digestAlgorithm,
532: privateKey)) != 0)
533: return (status);
534:
535: R_EncodePEMBlock
536: (encodedSignature, encodedSignatureLen, signature, signatureLen);
537:
538: if (recode)
539: R_EncodePEMBlock
540: (encodedContent, encodedContentLen, content, contentLen);
541:
542: return (0);
543: }
544:
545: int R_SignBlock
546: (signature, signatureLen, block, blockLen, digestAlgorithm, privateKey)
547: unsigned char *signature; /* signature */
548: unsigned int *signatureLen; /* length of signature */
549: unsigned char *block; /* block */
550: unsigned int blockLen; /* length of block */
551: int digestAlgorithm; /* message-digest algorithm */
552: R_RSA_PRIVATE_KEY *privateKey; /* signer's RSA private key */
553: {
554: R_SIGNATURE_CTX context;
555: int status;
556:
557: do {
558: if ((status = R_SignInit (&context, digestAlgorithm)) != 0)
559: break;
560: if ((status = R_SignUpdate (&context, block, blockLen)) != 0)
561: break;
562: if ((status = R_SignFinal (&context, signature, signatureLen, privateKey))
563: != 0)
564: break;
565: } while (0);
566:
567: /* Zeroize sensitive information. */
568: R_memset ((POINTER)&context, 0, sizeof (context));
569:
570: return (status);
571: }
572:
573: int R_VerifyPEMSignature
574: (content, contentLen, encodedContent, encodedContentLen, encodedSignature,
575: encodedSignatureLen, recode, digestAlgorithm, publicKey)
576: unsigned char *content; /* content */
577: unsigned int *contentLen; /* length of content */
578: unsigned char *encodedContent; /* (possibly) encoded content */
579: unsigned int encodedContentLen; /* length of encoded content */
580: unsigned char *encodedSignature; /* encoded signature */
581: unsigned int encodedSignatureLen; /* length of encoded signature */
582: int recode; /* recoding flag */
583: int digestAlgorithm; /* message-digest algorithm */
584: R_RSA_PUBLIC_KEY *publicKey; /* signer's RSA public key */
585: {
586: unsigned char signature[MAX_SIGNATURE_LEN];
587: unsigned int signatureLen;
588:
589: if (encodedSignatureLen > MAX_PEM_SIGNATURE_LEN)
590: return (RE_SIGNATURE_ENCODING);
591:
592: if (recode) {
593: if (R_DecodePEMBlock
594: (content, contentLen, encodedContent, encodedContentLen))
595: return (RE_CONTENT_ENCODING);
596: }
597: else {
598: content = encodedContent;
599: *contentLen = encodedContentLen;
600: }
601:
602: if (R_DecodePEMBlock
603: (signature, &signatureLen, encodedSignature, encodedSignatureLen))
604: return (RE_SIGNATURE_ENCODING);
605:
606: return (R_VerifyBlockSignature
607: (content, *contentLen, signature, signatureLen, digestAlgorithm,
608: publicKey));
609: }
610:
611: int R_VerifyBlockSignature
612: (block, blockLen, signature, signatureLen, digestAlgorithm, publicKey)
613: unsigned char *block; /* block */
614: unsigned int blockLen; /* length of block */
615: unsigned char *signature; /* signature */
616: unsigned int signatureLen; /* length of signature */
617: int digestAlgorithm; /* message-digest algorithm */
618: R_RSA_PUBLIC_KEY *publicKey; /* signer's RSA public key */
619: {
620: R_SIGNATURE_CTX context;
621: int status;
622:
623: do {
624: if ((status = R_VerifyInit (&context, digestAlgorithm)) != 0)
625: break;
626: if ((status = R_VerifyUpdate (&context, block, blockLen)) != 0)
627: break;
628: if ((status = R_VerifyFinal (&context, signature, signatureLen, publicKey))
629: != 0)
630: break;
631: } while (0);
632:
633: /* Zeroize sensitive information. */
634: R_memset ((POINTER)&context, 0, sizeof (context));
635:
636: return (status);
637: }
638:
639: int R_SealPEMBlock
640: (encryptedContent, encryptedContentLen, encryptedKey, encryptedKeyLen,
641: encryptedSignature, encryptedSignatureLen, iv, content, contentLen,
642: digestAlgorithm, publicKey, privateKey, randomStruct)
643: unsigned char *encryptedContent; /* encoded, encrypted content */
644: unsigned int *encryptedContentLen; /* length */
645: unsigned char *encryptedKey; /* encoded, encrypted key */
646: unsigned int *encryptedKeyLen; /* length */
647: unsigned char *encryptedSignature; /* encoded, encrypted signature */
648: unsigned int *encryptedSignatureLen; /* length */
649: unsigned char iv[8]; /* DES initialization vector */
650: unsigned char *content; /* content */
651: unsigned int contentLen; /* length of content */
652: int digestAlgorithm; /* message-digest algorithms */
653: R_RSA_PUBLIC_KEY *publicKey; /* recipient's RSA public key */
654: R_RSA_PRIVATE_KEY *privateKey; /* signer's RSA private key */
655: R_RANDOM_STRUCT *randomStruct; /* random structure */
656: {
657: R_ENVELOPE_CTX context;
658: R_RSA_PUBLIC_KEY *publicKeys[1];
659: int status;
660: unsigned char encryptedKeyBlock[MAX_ENCRYPTED_KEY_LEN],
661: signature[MAX_SIGNATURE_LEN], *encryptedKeys[1];
662: unsigned int signatureLen, encryptedKeyBlockLen;
663:
664: do {
665: if ((status = R_SignBlock
666: (signature, &signatureLen, content, contentLen, digestAlgorithm,
667: privateKey)) != 0)
668: break;
669:
670: publicKeys[0] = publicKey;
671: encryptedKeys[0] = encryptedKeyBlock;
672: if ((status = R_SealInit
673: (&context, encryptedKeys, &encryptedKeyBlockLen, iv, 1, publicKeys,
674: EA_DES_CBC, randomStruct)) != 0)
675: break;
676:
677: R_EncodePEMBlock
678: (encryptedKey, encryptedKeyLen, encryptedKeyBlock,
679: encryptedKeyBlockLen);
680:
681: EncryptPEMUpdateFinal
682: (&context, encryptedContent, encryptedContentLen, content,
683: contentLen);
684:
685: EncryptPEMUpdateFinal
686: (&context, encryptedSignature, encryptedSignatureLen, signature,
687: signatureLen);
688: } while (0);
689:
690: /* Zeroize sensitive information.
691: */
692: R_memset ((POINTER)&context, 0, sizeof (context));
693: R_memset ((POINTER)signature, 0, sizeof (signature));
694:
695: return (status);
696: }
697:
698: int R_OpenPEMBlock
699: (content, contentLen, encryptedContent, encryptedContentLen, encryptedKey,
700: encryptedKeyLen, encryptedSignature, encryptedSignatureLen,
701: iv, digestAlgorithm, privateKey, publicKey)
702: unsigned char *content; /* content */
703: unsigned int *contentLen; /* length of content */
704: unsigned char *encryptedContent; /* encoded, encrypted content */
705: unsigned int encryptedContentLen; /* length */
706: unsigned char *encryptedKey; /* encoded, encrypted key */
707: unsigned int encryptedKeyLen; /* length */
708: unsigned char *encryptedSignature; /* encoded, encrypted signature */
709: unsigned int encryptedSignatureLen; /* length */
710: unsigned char iv[8]; /* DES initialization vector */
711: int digestAlgorithm; /* message-digest algorithms */
712: R_RSA_PRIVATE_KEY *privateKey; /* recipient's RSA private key */
713: R_RSA_PUBLIC_KEY *publicKey; /* signer's RSA public key */
714: {
715: R_ENVELOPE_CTX context;
716: int status;
717: unsigned char encryptedKeyBlock[MAX_ENCRYPTED_KEY_LEN],
718: signature[MAX_SIGNATURE_LEN];
719: unsigned int encryptedKeyBlockLen, signatureLen;
720:
721: if (encryptedKeyLen > MAX_PEM_ENCRYPTED_KEY_LEN)
722: return (RE_KEY_ENCODING);
723:
724: if (encryptedSignatureLen > MAX_PEM_ENCRYPTED_SIGNATURE_LEN)
725: return (RE_SIGNATURE_ENCODING);
726:
727: do {
728: if (R_DecodePEMBlock
729: (encryptedKeyBlock, &encryptedKeyBlockLen, encryptedKey,
730: encryptedKeyLen) != 0) {
731: status = RE_KEY_ENCODING;
732: break;
733: }
734:
735: if ((status = R_OpenInit
736: (&context, EA_DES_CBC, encryptedKeyBlock, encryptedKeyBlockLen,
737: iv, privateKey)) != 0)
738: break;
739:
740: if ((status = DecryptPEMUpdateFinal
741: (&context, content, contentLen, encryptedContent,
742: encryptedContentLen)) != 0) {
743: if ((status == RE_LEN || status == RE_ENCODING))
744: status = RE_CONTENT_ENCODING;
745: else
746: status = RE_KEY;
747: break;
748: }
749:
750: if (status = DecryptPEMUpdateFinal
751: (&context, signature, &signatureLen, encryptedSignature,
752: encryptedSignatureLen)) {
753: if ((status == RE_LEN || status == RE_ENCODING))
754: status = RE_SIGNATURE_ENCODING;
755: else
756: status = RE_KEY;
757: break;
758: }
759:
760: if ((status = R_VerifyBlockSignature
761: (content, *contentLen, signature, signatureLen, digestAlgorithm,
762: publicKey)) != 0)
763: break;
764: } while (0);
765:
766: /* Zeroize sensitive information.
767: */
768: R_memset ((POINTER)&context, 0, sizeof (context));
769: R_memset ((POINTER)signature, 0, sizeof (signature));
770:
771: return (status);
772: }
773:
774: int R_DigestBlock (digest, digestLen, block, blockLen, digestAlgorithm)
775: unsigned char *digest; /* message digest */
776: unsigned int *digestLen; /* length of message digest */
777: unsigned char *block; /* block */
778: unsigned int blockLen; /* length of block */
779: int digestAlgorithm; /* message-digest algorithm */
780: {
781: R_DIGEST_CTX context;
782: int status;
783:
784: do {
785: if ((status = R_DigestInit (&context, digestAlgorithm)) != 0)
786: break;
787: if ((status = R_DigestUpdate (&context, block, blockLen)) != 0)
788: break;
789: if ((status = R_DigestFinal (&context, digest, digestLen)) != 0)
790: break;
791: } while (0);
792:
793: /* Zeroize sensitive information. */
794: R_memset ((POINTER)&context, 0, sizeof (context));
795:
796: return (status);
797: }
798:
799: /* Assumes digestAlgorithm is DA_MD2 or DA_MD5 and digest length is 16.
800: */
801: static void R_EncodeDigestInfo (digestInfo, digestAlgorithm, digest)
802: unsigned char *digestInfo; /* DigestInfo encoding */
803: int digestAlgorithm; /* message-digest algorithm */
804: unsigned char *digest; /* message digest */
805: {
806: R_memcpy
807: ((POINTER)digestInfo, (POINTER)DIGEST_INFO_A, DIGEST_INFO_A_LEN);
808:
809: digestInfo[DIGEST_INFO_A_LEN] =
810: (digestAlgorithm == DA_MD2) ? (unsigned char)2 : (unsigned char)5;
811:
812: R_memcpy
813: ((POINTER)&digestInfo[DIGEST_INFO_A_LEN + 1], (POINTER)DIGEST_INFO_B,
814: DIGEST_INFO_B_LEN);
815:
816: R_memcpy
817: ((POINTER)&digestInfo[DIGEST_INFO_A_LEN + 1 + DIGEST_INFO_B_LEN],
818: (POINTER)digest, 16);
819: }
820:
821: /* Call SealUpdate and SealFinal on the input and ASCII recode.
822: */
823: static void EncryptPEMUpdateFinal
824: (context, output, outputLen, input, inputLen)
825: R_ENVELOPE_CTX *context;
826: unsigned char *output; /* encrypted, encoded block */
827: unsigned int *outputLen; /* length of output */
828: unsigned char *input; /* block to encrypt */
829: unsigned int inputLen; /* length */
830: {
831: unsigned char encryptedPart[24];
832: unsigned int i, lastPartLen, tempLen, len;
833:
834: /* Choose a buffer size of 24 bytes to hold the temporary encrypted output
835: which will be encoded.
836: Encrypt and encode as many 24-byte blocks as possible.
837: */
838: for (i = 0; i < inputLen / 24; ++i) {
839: /* Assume part out length will equal part in length since it is
840: a multiple of 8. Also assume no error output. */
841: R_SealUpdate (context, encryptedPart, &tempLen, &input[24*i], 24);
842:
843: /* len is always 32 */
844: R_EncodePEMBlock (&output[32*i], &tempLen, encryptedPart, 24);
845: }
846:
847: /* Encrypt the last part into encryptedPart.
848: */
849: R_SealUpdate
850: (context, encryptedPart, &lastPartLen, &input[24*i], inputLen - 24*i);
851: R_SealFinal (context, encryptedPart + lastPartLen, &len);
852: lastPartLen += len;
853:
854: R_EncodePEMBlock (&output[32*i], &len, encryptedPart, lastPartLen);
855: *outputLen = 32*i + len;
856:
857: /* Zeroize sensitive information.
858: */
859: R_memset ((POINTER)encryptedPart, 0, sizeof (encryptedPart));
860: }
861:
862: static int DecryptPEMUpdateFinal (context, output, outputLen, input, inputLen)
863: R_ENVELOPE_CTX *context;
864: unsigned char *output; /* decoded, decrypted block */
865: unsigned int *outputLen; /* length of output */
866: unsigned char *input; /* encrypted, encoded block */
867: unsigned int inputLen; /* length */
868: {
869: int status;
870: unsigned char encryptedPart[24];
871: unsigned int i, len;
872:
873: do {
874: /* Choose a buffer size of 24 bytes to hold the temporary decoded output
875: which will be decrypted.
876: Decode and decrypt as many 32-byte input blocks as possible.
877: */
878: *outputLen = 0;
879: for (i = 0; i < inputLen/32; i++) {
880: /* len is always 24 */
881: if ((status = R_DecodePEMBlock
882: (encryptedPart, &len, &input[32*i], 32)) != 0)
883: break;
884:
885: /* Excpect no error return */
886: R_OpenUpdate (context, output, &len, encryptedPart, 24);
887: output += len;
888: *outputLen += len;
889: }
890: if (status)
891: break;
892:
893: /* Decode the last part */
894: if ((status = R_DecodePEMBlock
895: (encryptedPart, &len, &input[32*i], inputLen - 32*i)) != 0)
896: break;
897:
898: /* Decrypt the last part.
899: */
900: R_OpenUpdate (context, output, &len, encryptedPart, len);
901: output += len;
902: *outputLen += len;
903: if ((status = R_OpenFinal (context, output, &len)) != 0)
904: break;
905: *outputLen += len;
906: } while (0);
907:
908: /* Zeroize sensitive information.
909: */
910: R_memset ((POINTER)&context, 0, sizeof (context));
911: R_memset ((POINTER)encryptedPart, 0, sizeof (encryptedPart));
912:
913: return (status);
914: }
915:
916: static int CipherInit (context, encryptionAlgorithm, key, iv, encrypt)
917: R_ENVELOPE_CTX *context;
918: int encryptionAlgorithm;
919: unsigned char *key; /* DES key */
920: unsigned char *iv; /* DES initialization vector */
921: int encrypt; /* encrypt flag (1 = encrypt, 0 = decrypt) */
922: {
923: switch (encryptionAlgorithm) {
924: case EA_DES_CBC:
925: DES_CBCInit (&context->cipherContext.des, key, iv, encrypt);
926: return (0);
927: case EA_DESX_CBC:
928: DESX_CBCInit (&context->cipherContext.desx, key, iv, encrypt);
929: return (0);
930: case EA_DES_EDE2_CBC:
931: case EA_DES_EDE3_CBC:
932: DES3_CBCInit (&context->cipherContext.des3, key, iv, encrypt);
933: return (0);
934:
935: default:
936: return (RE_ENCRYPTION_ALGORITHM);
937: }
938: }
939:
940: /* Assume len is a multiple of 8.
941: */
942: static void CipherUpdate (context, output, input, len)
943: R_ENVELOPE_CTX *context;
944: unsigned char *output; /* output block */
945: unsigned char *input; /* input block */
946: unsigned int len; /* length of input and output blocks */
947: {
948: if (context->encryptionAlgorithm == EA_DES_CBC)
949: DES_CBCUpdate (&context->cipherContext.des, output, input, len);
950: else if (context->encryptionAlgorithm == EA_DESX_CBC)
951: DESX_CBCUpdate (&context->cipherContext.desx, output, input, len);
952: else
953: DES3_CBCUpdate (&context->cipherContext.des3, output, input, len);
954: }
955:
956: static void CipherRestart (context)
957: R_ENVELOPE_CTX *context;
958: {
959: if (context->encryptionAlgorithm == EA_DES_CBC)
960: DES_CBCRestart (&context->cipherContext.des);
961: else if (context->encryptionAlgorithm == EA_DESX_CBC)
962: DESX_CBCRestart (&context->cipherContext.desx);
963: else
964: DES3_CBCRestart (&context->cipherContext.des3);
965: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.