Annotation of rsaref/source/r_enhanc.c, revision 1.1.1.1

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.