]> andersk Git - moira.git/blame - util/rsaref/r_enhanc.c
Set creation time and creator information for new users.
[moira.git] / util / rsaref / r_enhanc.c
CommitLineData
bd940221 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
17static 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
23static 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
28static 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
39static void R_EncodeDigestInfo PROTO_LIST
40 ((unsigned char *, int, unsigned char *));
41static void EncryptPEMUpdateFinal PROTO_LIST
42 ((R_ENVELOPE_CTX *, unsigned char *, unsigned int *, unsigned char *,
43 unsigned int));
44static int DecryptPEMUpdateFinal PROTO_LIST
45 ((R_ENVELOPE_CTX *, unsigned char *, unsigned int *, unsigned char *,
46 unsigned int));
47static int CipherInit PROTO_LIST
48 ((R_ENVELOPE_CTX *, int, unsigned char *, unsigned char *, int));
49static void CipherUpdate PROTO_LIST
50 ((R_ENVELOPE_CTX *, unsigned char *, unsigned char *, unsigned int));
51static void CipherRestart PROTO_LIST ((R_ENVELOPE_CTX *));
52
53int R_DigestInit (context, digestAlgorithm)
54R_DIGEST_CTX *context; /* new context */
55int 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
75int R_DigestUpdate (context, partIn, partInLen)
76R_DIGEST_CTX *context; /* context */
77unsigned char *partIn; /* next data part */
78unsigned 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
87int R_DigestFinal (context, digest, digestLen)
88R_DIGEST_CTX *context; /* context */
89unsigned char *digest; /* message digest */
90unsigned 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
101int R_SignInit (context, digestAlgorithm)
102R_SIGNATURE_CTX *context; /* new context */
103int digestAlgorithm; /* message-digest algorithm */
104{
105 return (R_DigestInit (&context->digestContext, digestAlgorithm));
106}
107
108int R_SignUpdate (context, partIn, partInLen)
109R_SIGNATURE_CTX *context; /* context */
110unsigned char *partIn; /* next data part */
111unsigned int partInLen; /* length of next data part */
112{
113 return (R_DigestUpdate (&context->digestContext, partIn, partInLen));
114}
115
116int R_SignFinal (context, signature, signatureLen, privateKey)
117R_SIGNATURE_CTX *context; /* context */
118unsigned char *signature; /* signature */
119unsigned int *signatureLen; /* length of signature */
120R_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
154int R_VerifyInit (context, digestAlgorithm)
155R_SIGNATURE_CTX *context; /* new context */
156int digestAlgorithm; /* message-digest algorithm */
157{
158 return (R_DigestInit (&context->digestContext, digestAlgorithm));
159}
160
161int R_VerifyUpdate (context, partIn, partInLen)
162R_SIGNATURE_CTX *context; /* context */
163unsigned char *partIn; /* next data part */
164unsigned int partInLen; /* length of next data part */
165{
166 return (R_DigestUpdate (&context->digestContext, partIn, partInLen));
167}
168
169int R_VerifyFinal (context, signature, signatureLen, publicKey)
170R_SIGNATURE_CTX *context; /* context */
171unsigned char *signature; /* signature */
172unsigned int signatureLen; /* length of signature */
173R_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 */
223int R_SealInit
224 (context, encryptedKeys, encryptedKeyLens, iv, publicKeyCount, publicKeys,
225 encryptionAlgorithm, randomStruct)
226R_ENVELOPE_CTX *context; /* new context */
227unsigned char **encryptedKeys; /* encrypted keys */
228unsigned int *encryptedKeyLens; /* lengths of encrypted keys */
229unsigned char iv[8]; /* initialization vector */
230unsigned int publicKeyCount; /* number of public keys */
231R_RSA_PUBLIC_KEY **publicKeys; /* public keys */
232int encryptionAlgorithm; /* data encryption algorithm */
233R_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 */
279int R_SealUpdate (context, partOut, partOutLen, partIn, partInLen)
280R_ENVELOPE_CTX *context; /* context */
281unsigned char *partOut; /* next encrypted data part */
282unsigned int *partOutLen; /* length of next encrypted data part */
283unsigned char *partIn; /* next data part */
284unsigned 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 */
330int R_SealFinal (context, partOut, partOutLen)
331R_ENVELOPE_CTX *context; /* context */
332unsigned char *partOut; /* last encrypted data part */
333unsigned 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 */
355int R_OpenInit
356 (context, encryptionAlgorithm, encryptedKey, encryptedKeyLen, iv, privateKey)
357R_ENVELOPE_CTX *context; /* new context */
358int encryptionAlgorithm; /* data encryption algorithm */
359unsigned char *encryptedKey; /* encrypted data encryption key */
360unsigned int encryptedKeyLen; /* length of encrypted key */
361unsigned char iv[8]; /* initialization vector */
362R_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 */
409int R_OpenUpdate (context, partOut, partOutLen, partIn, partInLen)
410R_ENVELOPE_CTX *context; /* context */
411unsigned char *partOut; /* next recovered data part */
412unsigned int *partOutLen; /* length of next recovered data part */
413unsigned char *partIn; /* next encrypted data part */
414unsigned 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 */
462int R_OpenFinal (context, partOut, partOutLen)
463R_ENVELOPE_CTX *context; /* context */
464unsigned char *partOut; /* last recovered data part */
465unsigned 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
513int R_SignPEMBlock
514 (encodedContent, encodedContentLen, encodedSignature, encodedSignatureLen,
515 content, contentLen, recode, digestAlgorithm, privateKey)
516unsigned char *encodedContent; /* encoded content */
517unsigned int *encodedContentLen; /* length of encoded content */
518unsigned char *encodedSignature; /* encoded signature */
519unsigned int *encodedSignatureLen; /* length of encoded signature */
520unsigned char *content; /* content */
521unsigned int contentLen; /* length of content */
522int recode; /* recoding flag */
523int digestAlgorithm; /* message-digest algorithm */
524R_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
545int R_SignBlock
546 (signature, signatureLen, block, blockLen, digestAlgorithm, privateKey)
547unsigned char *signature; /* signature */
548unsigned int *signatureLen; /* length of signature */
549unsigned char *block; /* block */
550unsigned int blockLen; /* length of block */
551int digestAlgorithm; /* message-digest algorithm */
552R_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
573int R_VerifyPEMSignature
574 (content, contentLen, encodedContent, encodedContentLen, encodedSignature,
575 encodedSignatureLen, recode, digestAlgorithm, publicKey)
576unsigned char *content; /* content */
577unsigned int *contentLen; /* length of content */
578unsigned char *encodedContent; /* (possibly) encoded content */
579unsigned int encodedContentLen; /* length of encoded content */
580unsigned char *encodedSignature; /* encoded signature */
581unsigned int encodedSignatureLen; /* length of encoded signature */
582int recode; /* recoding flag */
583int digestAlgorithm; /* message-digest algorithm */
584R_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
611int R_VerifyBlockSignature
612 (block, blockLen, signature, signatureLen, digestAlgorithm, publicKey)
613unsigned char *block; /* block */
614unsigned int blockLen; /* length of block */
615unsigned char *signature; /* signature */
616unsigned int signatureLen; /* length of signature */
617int digestAlgorithm; /* message-digest algorithm */
618R_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
639int R_SealPEMBlock
640 (encryptedContent, encryptedContentLen, encryptedKey, encryptedKeyLen,
641 encryptedSignature, encryptedSignatureLen, iv, content, contentLen,
642 digestAlgorithm, publicKey, privateKey, randomStruct)
643unsigned char *encryptedContent; /* encoded, encrypted content */
644unsigned int *encryptedContentLen; /* length */
645unsigned char *encryptedKey; /* encoded, encrypted key */
646unsigned int *encryptedKeyLen; /* length */
647unsigned char *encryptedSignature; /* encoded, encrypted signature */
648unsigned int *encryptedSignatureLen; /* length */
649unsigned char iv[8]; /* DES initialization vector */
650unsigned char *content; /* content */
651unsigned int contentLen; /* length of content */
652int digestAlgorithm; /* message-digest algorithms */
653R_RSA_PUBLIC_KEY *publicKey; /* recipient's RSA public key */
654R_RSA_PRIVATE_KEY *privateKey; /* signer's RSA private key */
655R_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
698int R_OpenPEMBlock
699 (content, contentLen, encryptedContent, encryptedContentLen, encryptedKey,
700 encryptedKeyLen, encryptedSignature, encryptedSignatureLen,
701 iv, digestAlgorithm, privateKey, publicKey)
702unsigned char *content; /* content */
703unsigned int *contentLen; /* length of content */
704unsigned char *encryptedContent; /* encoded, encrypted content */
705unsigned int encryptedContentLen; /* length */
706unsigned char *encryptedKey; /* encoded, encrypted key */
707unsigned int encryptedKeyLen; /* length */
708unsigned char *encryptedSignature; /* encoded, encrypted signature */
709unsigned int encryptedSignatureLen; /* length */
710unsigned char iv[8]; /* DES initialization vector */
711int digestAlgorithm; /* message-digest algorithms */
712R_RSA_PRIVATE_KEY *privateKey; /* recipient's RSA private key */
713R_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
774int R_DigestBlock (digest, digestLen, block, blockLen, digestAlgorithm)
775unsigned char *digest; /* message digest */
776unsigned int *digestLen; /* length of message digest */
777unsigned char *block; /* block */
778unsigned int blockLen; /* length of block */
779int 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 */
801static void R_EncodeDigestInfo (digestInfo, digestAlgorithm, digest)
802unsigned char *digestInfo; /* DigestInfo encoding */
803int digestAlgorithm; /* message-digest algorithm */
804unsigned 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 */
823static void EncryptPEMUpdateFinal
824 (context, output, outputLen, input, inputLen)
825R_ENVELOPE_CTX *context;
826unsigned char *output; /* encrypted, encoded block */
827unsigned int *outputLen; /* length of output */
828unsigned char *input; /* block to encrypt */
829unsigned 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
862static int DecryptPEMUpdateFinal (context, output, outputLen, input, inputLen)
863R_ENVELOPE_CTX *context;
864unsigned char *output; /* decoded, decrypted block */
865unsigned int *outputLen; /* length of output */
866unsigned char *input; /* encrypted, encoded block */
867unsigned 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
916static int CipherInit (context, encryptionAlgorithm, key, iv, encrypt)
917R_ENVELOPE_CTX *context;
918int encryptionAlgorithm;
919unsigned char *key; /* DES key */
920unsigned char *iv; /* DES initialization vector */
921int 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 */
942static void CipherUpdate (context, output, input, len)
943R_ENVELOPE_CTX *context;
944unsigned char *output; /* output block */
945unsigned char *input; /* input block */
946unsigned 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
956static void CipherRestart (context)
957R_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 page took 0.185109 seconds and 5 git commands to generate.