|
|
1.1 root 1: /* R_ENHANC.C - cryptographic enhancements for RSAREF
2: */
3:
4: /* Copyright (C) 1991-2 RSA Laboratories, a division of RSA Data
5: Security, Inc. All rights reserved.
6: */
7:
8: #include "global.h"
9: #include "rsaref.h"
10: #include "r_encode.h"
11: #include "r_random.h"
12: #include "rsa.h"
13: #include "md2.h"
14: #include "md5.h"
15: #include "des.h"
16:
17: /* DigestInfo encoding is DIGEST_INFO_A, then 2 or 5 (for MD2/MD5),
18: then DIGEST_INFO_B, then 16-byte message digest.
19: */
20:
21: static char DIGEST_INFO_A[] = {
22: 0x30, 0x20, 0x30, 0x0c, 0x06, 0x08, 0x2a, 0x86, 0x48, 0x86, 0xf7,
23: 0x0d, 0x02
24: };
25: #define DIGEST_INFO_A_LEN sizeof (DIGEST_INFO_A)
26:
27: static char DIGEST_INFO_B[] = { 0x05, 0x00, 0x04, 0x10 };
28: #define DIGEST_INFO_B_LEN sizeof (DIGEST_INFO_B)
29:
30: #define DIGEST_INFO_LEN (DIGEST_INFO_A_LEN + 1 + DIGEST_INFO_B_LEN + 16)
31:
32: static unsigned char *PADDING[] = {
33: (unsigned char *)"", (unsigned char *)"\001", (unsigned char *)"\002\002",
34: (unsigned char *)"\003\003\003", (unsigned char *)"\004\004\004\004",
35: (unsigned char *)"\005\005\005\005\005",
36: (unsigned char *)"\006\006\006\006\006\006",
37: (unsigned char *)"\007\007\007\007\007\007\007",
38: (unsigned char *)"\010\010\010\010\010\010\010\010"
39: };
40:
41: #define MAX_ENCRYPTED_KEY_LEN MAX_RSA_MODULUS_LEN
42:
43: static int R_SignBlock PROTO_LIST
44: ((unsigned char *, unsigned int *, unsigned char *, unsigned int, int,
45: R_RSA_PRIVATE_KEY *));
46: static void R_EncodeDigestInfo PROTO_LIST
47: ((unsigned char *, int, unsigned char *));
48: static void R_EncryptPEMBlock PROTO_LIST
49: ((unsigned char *, unsigned int *, unsigned char *, unsigned int,
50: unsigned char [8], unsigned char [8]));
51: static int R_DecryptPEMBlock PROTO_LIST
52: ((unsigned char *, unsigned int *, unsigned char *, unsigned int,
53: unsigned char [8], unsigned char [8]));
54:
55: int R_SignPEMBlock
56: (encodedContent, encodedContentLen, encodedSignature, encodedSignatureLen,
57: content, contentLen, recode, digestAlgorithm, privateKey)
58: unsigned char *encodedContent; /* encoded content */
59: unsigned int *encodedContentLen; /* length of encoded content */
60: unsigned char *encodedSignature; /* encoded signature */
61: unsigned int *encodedSignatureLen; /* length of encoded signature */
62: unsigned char *content; /* content */
63: unsigned int contentLen; /* length of content */
64: int recode; /* recoding flag */
65: int digestAlgorithm; /* message-digest algorithm */
66: R_RSA_PRIVATE_KEY *privateKey; /* signer's RSA private key */
67: {
68: int status;
69: unsigned char signature[MAX_SIGNATURE_LEN];
70: unsigned int signatureLen;
71:
72: if (status = R_SignBlock
73: (signature, &signatureLen, content, contentLen, digestAlgorithm,
74: privateKey))
75: return (status);
76:
77: R_EncodePEMBlock
78: (encodedSignature, encodedSignatureLen, signature, signatureLen);
79:
80: if (recode)
81: R_EncodePEMBlock
82: (encodedContent, encodedContentLen, content, contentLen);
83:
84: return (0);
85: }
86:
87: int R_VerifyPEMSignature
88: (content, contentLen, encodedContent, encodedContentLen, encodedSignature,
89: encodedSignatureLen, recode, digestAlgorithm, publicKey)
90: unsigned char *content; /* content */
91: unsigned int *contentLen; /* length of content */
92: unsigned char *encodedContent; /* (possibly) encoded content */
93: unsigned int encodedContentLen; /* length of encoded content */
94: unsigned char *encodedSignature; /* encoded signature */
95: unsigned int encodedSignatureLen; /* length of encoded signature */
96: int recode; /* recoding flag */
97: int digestAlgorithm; /* message-digest algorithm */
98: R_RSA_PUBLIC_KEY *publicKey; /* signer's RSA public key */
99: {
100: int status;
101: unsigned char signature[MAX_SIGNATURE_LEN];
102: unsigned int signatureLen;
103:
104: if (encodedSignatureLen > MAX_PEM_SIGNATURE_LEN)
105: return (RE_SIGNATURE_ENCODING);
106:
107: if (recode) {
108: if (status = R_DecodePEMBlock
109: (content, contentLen, encodedContent, encodedContentLen))
110: return (RE_CONTENT_ENCODING);
111: }
112: else {
113: content = encodedContent;
114: *contentLen = encodedContentLen;
115: }
116:
117: if (status = R_DecodePEMBlock
118: (signature, &signatureLen, encodedSignature, encodedSignatureLen))
119: return (RE_SIGNATURE_ENCODING);
120:
121: return (R_VerifyBlockSignature
122: (content, *contentLen, signature, signatureLen, digestAlgorithm,
123: publicKey));
124: }
125:
126: int R_VerifyBlockSignature
127: (block, blockLen, signature, signatureLen, digestAlgorithm, publicKey)
128: unsigned char *block; /* block */
129: unsigned int blockLen; /* length of block */
130: unsigned char *signature; /* signature */
131: unsigned int signatureLen; /* length of signature */
132: int digestAlgorithm; /* message-digest algorithm */
133: R_RSA_PUBLIC_KEY *publicKey; /* signer's RSA public key */
134: {
135: int status;
136: unsigned char digest[MAX_DIGEST_LEN], digestInfo[DIGEST_INFO_LEN],
137: originalDigestInfo[MAX_SIGNATURE_LEN];
138: unsigned int digestLen, originalDigestInfoLen;
139:
140: if (signatureLen > MAX_SIGNATURE_LEN)
141: return (RE_SIGNATURE);
142:
143: do {
144: if (status = R_DigestBlock
145: (digest, &digestLen, block, blockLen, digestAlgorithm))
146: break;
147:
148: R_EncodeDigestInfo (digestInfo, digestAlgorithm, digest);
149:
150: if (status = RSAPublicDecrypt
151: (originalDigestInfo, &originalDigestInfoLen, signature, signatureLen,
152: publicKey)) {
153: status = RE_PUBLIC_KEY;
154: break;
155: }
156:
157: if ((originalDigestInfoLen != DIGEST_INFO_LEN) ||
158: (R_memcmp
159: ((POINTER)originalDigestInfo, (POINTER)digestInfo,
160: DIGEST_INFO_LEN))) {
161: status = RE_SIGNATURE;
162: break;
163: }
164:
165: } while (0);
166:
167: /* Zeroize potentially sensitive information.
168: */
169: R_memset ((POINTER)digest, 0, sizeof (digest));
170: R_memset ((POINTER)digestInfo, 0, sizeof (digestInfo));
171: R_memset ((POINTER)originalDigestInfo, 0, sizeof (originalDigestInfo));
172:
173: return (status);
174: }
175:
176: int R_SealPEMBlock
177: (encryptedContent, encryptedContentLen, encryptedKey, encryptedKeyLen,
178: encryptedSignature, encryptedSignatureLen, iv, content, contentLen,
179: digestAlgorithm, publicKey, privateKey, randomStruct)
180: unsigned char *encryptedContent; /* encoded, encrypted content */
181: unsigned int *encryptedContentLen; /* length */
182: unsigned char *encryptedKey; /* encoded, encrypted key */
183: unsigned int *encryptedKeyLen; /* length */
184: unsigned char *encryptedSignature; /* encoded, encrypted signature */
185: unsigned int *encryptedSignatureLen; /* length */
186: unsigned char iv[8]; /* DES initializing vector */
187: unsigned char *content; /* content */
188: unsigned int contentLen; /* length of content */
189: int digestAlgorithm; /* message-digest algorithm */
190: R_RSA_PUBLIC_KEY *publicKey; /* recipient's RSA public key */
191: R_RSA_PRIVATE_KEY *privateKey; /* signer's RSA private key */
192: R_RANDOM_STRUCT *randomStruct; /* random structure */
193: {
194: int status;
195: unsigned char encryptedKeyBlock[MAX_ENCRYPTED_KEY_LEN], key[8],
196: signature[MAX_SIGNATURE_LEN];
197: unsigned int encryptedKeyBlockLen, signatureLen;
198:
199: do {
200: if (status = R_SignBlock
201: (signature, &signatureLen, content, contentLen, digestAlgorithm,
202: privateKey))
203: break;
204:
205: if ((status = R_GenerateBytes (key, 8, randomStruct)) ||
206: (status = R_GenerateBytes (iv, 8, randomStruct)))
207: break;
208:
209: R_EncryptPEMBlock
210: (encryptedContent, encryptedContentLen, content, contentLen, key, iv);
211:
212: if (status = RSAPublicEncrypt
213: (encryptedKeyBlock, &encryptedKeyBlockLen, key, 8, publicKey,
214: randomStruct)) {
215: status = RE_PUBLIC_KEY;
216: break;
217: }
218:
219: R_EncodePEMBlock
220: (encryptedKey, encryptedKeyLen, encryptedKeyBlock,
221: encryptedKeyBlockLen);
222:
223: R_EncryptPEMBlock
224: (encryptedSignature, encryptedSignatureLen, signature, signatureLen,
225: key, iv);
226:
227: } while (0);
228:
229: /* Zeroize sensitive information.
230: */
231: R_memset ((POINTER)key, 0, sizeof (key));
232: R_memset ((POINTER)signature, 0, sizeof (signature));
233:
234: return (status);
235: }
236:
237: int R_OpenPEMBlock
238: (content, contentLen, encryptedContent, encryptedContentLen, encryptedKey,
239: encryptedKeyLen, encryptedSignature, encryptedSignatureLen,
240: iv, digestAlgorithm, privateKey, publicKey)
241: unsigned char *content; /* content */
242: unsigned int *contentLen; /* length of content */
243: unsigned char *encryptedContent; /* encoded, encrypted content */
244: unsigned int encryptedContentLen; /* length */
245: unsigned char *encryptedKey; /* encoded, encrypted key */
246: unsigned int encryptedKeyLen; /* length */
247: unsigned char *encryptedSignature; /* encoded, encrypted signature */
248: unsigned int encryptedSignatureLen; /* length */
249: unsigned char iv[8]; /* DES initializing vector */
250: int digestAlgorithm; /* message-digest algorithm */
251: R_RSA_PRIVATE_KEY *privateKey; /* recipient's RSA private key */
252: R_RSA_PUBLIC_KEY *publicKey; /* signer's RSA public key */
253: {
254: int status;
255: unsigned char encryptedKeyBlock[MAX_ENCRYPTED_KEY_LEN],
256: key[MAX_ENCRYPTED_KEY_LEN], signature[MAX_SIGNATURE_LEN];
257: unsigned int encryptedKeyBlockLen, keyLen, signatureLen;
258:
259: if (encryptedKeyLen > MAX_PEM_ENCRYPTED_KEY_LEN)
260: return (RE_KEY_ENCODING);
261:
262: if (encryptedSignatureLen > MAX_PEM_ENCRYPTED_SIGNATURE_LEN)
263: return (RE_SIGNATURE_ENCODING);
264:
265: do {
266: if (status = R_DecodePEMBlock
267: (encryptedKeyBlock, &encryptedKeyBlockLen, encryptedKey,
268: encryptedKeyLen)) {
269: status = RE_KEY_ENCODING;
270: break;
271: }
272:
273: if (status = RSAPrivateDecrypt
274: (key, &keyLen, encryptedKeyBlock, encryptedKeyBlockLen, privateKey)) {
275: status = RE_PRIVATE_KEY;
276: break;
277: }
278:
279: if (keyLen != 8) {
280: status = RE_PRIVATE_KEY;
281: break;
282: }
283:
284: if (status = R_DecryptPEMBlock
285: (content, contentLen, encryptedContent, encryptedContentLen, key,
286: iv)) {
287: if ((status == RE_LEN || status == RE_ENCODING))
288: status = RE_CONTENT_ENCODING;
289: else
290: status = RE_KEY;
291: break;
292: }
293:
294: if (status = R_DecryptPEMBlock
295: (signature, &signatureLen, encryptedSignature, encryptedSignatureLen,
296: key, iv)) {
297: if ((status == RE_LEN || status == RE_ENCODING))
298: status = RE_SIGNATURE_ENCODING;
299: else
300: status = RE_KEY;
301: }
302:
303: if (status = R_VerifyBlockSignature
304: (content, *contentLen, signature, signatureLen, digestAlgorithm,
305: publicKey))
306: break;
307:
308: } while (0);
309:
310: /* Zeroize sensitive information.
311: */
312: R_memset ((POINTER)key, 0, sizeof (key));
313: R_memset ((POINTER)signature, 0, sizeof (signature));
314:
315: return (status);
316: }
317:
318: static int R_SignBlock
319: (signature, signatureLen, block, blockLen, digestAlgorithm, privateKey)
320: unsigned char *signature; /* signature */
321: unsigned int *signatureLen; /* length of signature */
322: unsigned char *block; /* block */
323: unsigned int blockLen; /* length of block */
324: int digestAlgorithm; /* message-digest algorithm */
325: R_RSA_PRIVATE_KEY *privateKey; /* signer's RSA private key */
326: {
327: int status;
328: unsigned char digest[MAX_DIGEST_LEN], digestInfo[DIGEST_INFO_LEN];
329: unsigned int digestLen;
330:
331: do {
332: if (status = R_DigestBlock
333: (digest, &digestLen, block, blockLen, digestAlgorithm))
334: break;
335:
336: R_EncodeDigestInfo (digestInfo, digestAlgorithm, digest);
337:
338: if (status = RSAPrivateEncrypt
339: (signature, signatureLen, digestInfo, DIGEST_INFO_LEN, privateKey)) {
340: status = RE_PRIVATE_KEY;
341: break;
342: }
343:
344: } while (0);
345:
346: /* Zeroize potentially sensitive information.
347: */
348: R_memset ((POINTER)digest, 0, sizeof (digest));
349: R_memset ((POINTER)digestInfo, 0, sizeof (digestInfo));
350:
351: return (status);
352: }
353:
354: int R_DigestBlock (digest, digestLen, block, blockLen, digestAlgorithm)
355: unsigned char *digest; /* message digest */
356: unsigned int *digestLen; /* length of message digest */
357: unsigned char *block; /* block */
358: unsigned int blockLen; /* length of block */
359: int digestAlgorithm; /* message-digest algorithm */
360: {
361: MD2_CTX md2Context;
362: MD5_CTX md5Context;
363: int status;
364:
365: status = 0;
366:
367: switch (digestAlgorithm) {
368: case DA_MD2:
369: MD2Init (&md2Context);
370: MD2Update (&md2Context, block, blockLen);
371: MD2Final (digest, &md2Context);
372: *digestLen = 16;
373: break;
374:
375: case DA_MD5:
376: MD5Init (&md5Context);
377: MD5Update (&md5Context, block, blockLen);
378: MD5Final (digest, &md5Context);
379: *digestLen = 16;
380: break;
381:
382: default:
383: status = RE_DIGEST_ALGORITHM;
384: }
385:
386: return (status);
387: }
388:
389: /* Assumes digestAlgorithm is DA_MD2 or DA_MD5 and digest length is 16.
390: */
391: static void R_EncodeDigestInfo (digestInfo, digestAlgorithm, digest)
392: unsigned char *digestInfo; /* DigestInfo encoding */
393: int digestAlgorithm; /* message-digest algorithm */
394: unsigned char *digest; /* message digest */
395: {
396: R_memcpy
397: ((POINTER)digestInfo, (POINTER)DIGEST_INFO_A, DIGEST_INFO_A_LEN);
398:
399: digestInfo[DIGEST_INFO_A_LEN] =
400: (digestAlgorithm == DA_MD2) ? (unsigned char)2 : (unsigned char)5;
401:
402: R_memcpy
403: ((POINTER)&digestInfo[DIGEST_INFO_A_LEN + 1], (POINTER)DIGEST_INFO_B,
404: DIGEST_INFO_B_LEN);
405:
406: R_memcpy
407: ((POINTER)&digestInfo[DIGEST_INFO_A_LEN + 1 + DIGEST_INFO_B_LEN],
408: (POINTER)digest, 16);
409: }
410:
411: static void R_EncryptPEMBlock
412: (encryptedBlock, encryptedBlockLen, block, blockLen, key, iv)
413: unsigned char *encryptedBlock; /* encrypted, encoded block */
414: unsigned int *encryptedBlockLen; /* length */
415: unsigned char *block; /* block */
416: unsigned int blockLen; /* length of block */
417: unsigned char key[8]; /* DES key */
418: unsigned char iv[8]; /* DES initialization vector */
419: {
420: DES_CBC_CTX context;
421: unsigned char encryptedPart[24], lastPart[24];
422: unsigned int i, lastPartLen, len, padLen;
423:
424: DES_CBCInit (&context, key, iv, 1);
425:
426: for (i = 0; i < blockLen/24; i++) {
427: DES_CBCUpdate (&context, encryptedPart, &block[24*i], 24);
428: /* len is always 32 */
429: R_EncodePEMBlock (&encryptedBlock[32*i], &len, encryptedPart, 24);
430: }
431:
432: padLen = 8 - (blockLen % 8);
433: lastPartLen = blockLen - 24*i + padLen;
434: R_memcpy ((POINTER)lastPart, (POINTER)&block[24*i], lastPartLen - padLen);
435: R_memcpy
436: ((POINTER)&lastPart[lastPartLen - padLen], PADDING[padLen], padLen);
437: DES_CBCUpdate (&context, encryptedPart, lastPart, lastPartLen);
438: R_EncodePEMBlock
439: (&encryptedBlock[32*i], &len, encryptedPart, lastPartLen);
440: *encryptedBlockLen = 32*i + len;
441:
442: DES_CBCFinal (&context);
443:
444: /* Zeroize sensitive information.
445: */
446: R_memset ((POINTER)lastPart, 0, sizeof (lastPart));
447: }
448:
449: static int R_DecryptPEMBlock
450: (block, blockLen, encryptedBlock, encryptedBlockLen, key, iv)
451: unsigned char *block; /* block */
452: unsigned int *blockLen; /* length of block */
453: unsigned char *encryptedBlock; /* encrypted, encoded block */
454: unsigned int encryptedBlockLen; /* length */
455: unsigned char key[8]; /* DES key */
456: unsigned char iv[8]; /* DES initialization vector */
457: {
458: DES_CBC_CTX context;
459: int status;
460: unsigned char encryptedPart[24], lastPart[24];
461: unsigned int i, lastPartLen, len, padLen;
462:
463: if (encryptedBlockLen < 1)
464: return (RE_LEN);
465:
466: DES_CBCInit (&context, key, iv, 0);
467:
468: status = 0;
469:
470: do {
471: for (i = 0; i < (encryptedBlockLen-1)/32; i++) {
472: /* len is always 24 */
473: if (status = R_DecodePEMBlock
474: (encryptedPart, &len, &encryptedBlock[32*i], 32))
475: break;
476: DES_CBCUpdate (&context, &block[24*i], encryptedPart, 24);
477: }
478: if (status)
479: break;
480:
481: len = encryptedBlockLen - 32*i;
482: if (status = R_DecodePEMBlock
483: (encryptedPart, &lastPartLen, &encryptedBlock[32*i], len))
484: break;
485:
486: if (lastPartLen % 8) {
487: status = RE_DATA;
488: break;
489: }
490:
491: DES_CBCUpdate (&context, lastPart, encryptedPart, lastPartLen);
492:
493: padLen = lastPart[lastPartLen - 1];
494: if (padLen > 8) {
495: status = RE_DATA;
496: break;
497: }
498: if (R_memcmp
499: ((POINTER)&lastPart[lastPartLen - padLen], PADDING[padLen], padLen)) {
500: status = RE_DATA;
501: break;
502: }
503:
504: R_memcpy ((POINTER)&block[24*i], (POINTER)lastPart, lastPartLen - padLen);
505: *blockLen = 24*i + lastPartLen - padLen;
506:
507: } while (0);
508:
509: DES_CBCFinal (&context);
510:
511: /* Zeroize sensitive information.
512: */
513: R_memset ((POINTER)lastPart, 0, sizeof (lastPart));
514:
515: return (status);
516: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.