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

1.1       root        1: /* RSA.C - RSA routines 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_random.h"
                     11: #include "rsa.h"
                     12: #include "nn.h"
                     13: 
                     14: static int RSAPublicBlock PROTO_LIST 
                     15:   ((unsigned char *, unsigned int *, unsigned char *, unsigned int,
                     16:     R_RSA_PUBLIC_KEY *));
                     17: static int RSAPrivateBlock PROTO_LIST 
                     18:   ((unsigned char *, unsigned int *, unsigned char *, unsigned int,
                     19:     R_RSA_PRIVATE_KEY *));
                     20: 
                     21: /* RSA public-key encryption, according to PKCS #1.
                     22:  */
                     23: int RSAPublicEncrypt
                     24:   (output, outputLen, input, inputLen, publicKey, randomStruct)
                     25: unsigned char *output;                                      /* output block */
                     26: unsigned int *outputLen;                          /* length of output block */
                     27: unsigned char *input;                                        /* input block */
                     28: unsigned int inputLen;                             /* length of input block */
                     29: R_RSA_PUBLIC_KEY *publicKey;                              /* RSA public key */
                     30: R_RANDOM_STRUCT *randomStruct;                          /* random structure */
                     31: {
                     32:   int status;
                     33:   unsigned char byte, pkcsBlock[MAX_RSA_MODULUS_LEN];
                     34:   unsigned int i, modulusLen;
                     35:   
                     36:   modulusLen = (publicKey->bits + 7) / 8;
                     37:   if (inputLen + 11 > modulusLen)
                     38:     return (RE_LEN);
                     39:   
                     40:   pkcsBlock[0] = 0;
                     41:   /* block type 2 */
                     42:   pkcsBlock[1] = 2;
                     43: 
                     44:   for (i = 2; i < modulusLen - inputLen - 1; i++) {
                     45:     /* Find nonzero random byte.
                     46:      */
                     47:     do {
                     48:       R_GenerateBytes (&byte, 1, randomStruct);
                     49:     } while (byte == 0);
                     50:     pkcsBlock[i] = byte;
                     51:   }
                     52:   /* separator */
                     53:   pkcsBlock[i++] = 0;
                     54:   
                     55:   R_memcpy ((POINTER)&pkcsBlock[i], (POINTER)input, inputLen);
                     56:   
                     57:   status = RSAPublicBlock
                     58:     (output, outputLen, pkcsBlock, modulusLen, publicKey);
                     59:   
                     60:   /* Zeroize sensitive information.
                     61:    */
                     62:   byte = 0;
                     63:   R_memset ((POINTER)pkcsBlock, 0, sizeof (pkcsBlock));
                     64:   
                     65:   return (status);
                     66: }
                     67: 
                     68: /* RSA public-key decryption, according to PKCS #1.
                     69:  */
                     70: int RSAPublicDecrypt (output, outputLen, input, inputLen, publicKey)
                     71: unsigned char *output;                                      /* output block */
                     72: unsigned int *outputLen;                          /* length of output block */
                     73: unsigned char *input;                                        /* input block */
                     74: unsigned int inputLen;                             /* length of input block */
                     75: R_RSA_PUBLIC_KEY *publicKey;                              /* RSA public key */
                     76: {
                     77:   int status;
                     78:   unsigned char pkcsBlock[MAX_RSA_MODULUS_LEN];
                     79:   unsigned int i, modulusLen, pkcsBlockLen;
                     80:   
                     81:   modulusLen = (publicKey->bits + 7) / 8;
                     82:   if (inputLen > modulusLen)
                     83:     return (RE_LEN);
                     84:   
                     85:   if (status = RSAPublicBlock
                     86:       (pkcsBlock, &pkcsBlockLen, input, inputLen, publicKey))
                     87:     return (status);
                     88:   
                     89:   if (pkcsBlockLen != modulusLen)
                     90:     return (RE_LEN);
                     91:   
                     92:   /* Require block type 1.
                     93:    */
                     94:   if ((pkcsBlock[0] != 0) || (pkcsBlock[1] != 1))
                     95:    return (RE_DATA);
                     96: 
                     97:   for (i = 2; i < modulusLen-1; i++)
                     98:     if (pkcsBlock[i] != 0xff)
                     99:       break;
                    100:     
                    101:   /* separator */
                    102:   if (pkcsBlock[i++] != 0)
                    103:     return (RE_DATA);
                    104:   
                    105:   *outputLen = modulusLen - i;
                    106:   
                    107:   if (*outputLen + 11 > modulusLen)
                    108:     return (RE_DATA);
                    109: 
                    110:   R_memcpy ((POINTER)output, (POINTER)&pkcsBlock[i], *outputLen);
                    111:   
                    112:   /* Zeroize potentially sensitive information.
                    113:    */
                    114:   R_memset ((POINTER)pkcsBlock, 0, sizeof (pkcsBlock));
                    115:   
                    116:   return (0);
                    117: }
                    118: 
                    119: /* RSA private-key encryption, according to PKCS #1.
                    120:  */
                    121: int RSAPrivateEncrypt (output, outputLen, input, inputLen, privateKey)
                    122: unsigned char *output;                                      /* output block */
                    123: unsigned int *outputLen;                          /* length of output block */
                    124: unsigned char *input;                                        /* input block */
                    125: unsigned int inputLen;                             /* length of input block */
                    126: R_RSA_PRIVATE_KEY *privateKey;                           /* RSA private key */
                    127: {
                    128:   int status;
                    129:   unsigned char pkcsBlock[MAX_RSA_MODULUS_LEN];
                    130:   unsigned int i, modulusLen;
                    131:   
                    132:   modulusLen = (privateKey->bits + 7) / 8;
                    133:   if (inputLen + 11 > modulusLen)
                    134:     return (RE_LEN);
                    135:   
                    136:   pkcsBlock[0] = 0;
                    137:   /* block type 1 */
                    138:   pkcsBlock[1] = 1;
                    139: 
                    140:   for (i = 2; i < modulusLen - inputLen - 1; i++)
                    141:     pkcsBlock[i] = 0xff;
                    142: 
                    143:   /* separator */
                    144:   pkcsBlock[i++] = 0;
                    145:   
                    146:   R_memcpy ((POINTER)&pkcsBlock[i], (POINTER)input, inputLen);
                    147:   
                    148:   status = RSAPrivateBlock
                    149:     (output, outputLen, pkcsBlock, modulusLen, privateKey);
                    150: 
                    151:   /* Zeroize potentially sensitive information.
                    152:    */
                    153:   R_memset ((POINTER)pkcsBlock, 0, sizeof (pkcsBlock));
                    154: 
                    155:   return (status);
                    156: }
                    157: 
                    158: /* RSA private-key decryption, according to PKCS #1.
                    159:  */
                    160: int RSAPrivateDecrypt (output, outputLen, input, inputLen, privateKey)
                    161: unsigned char *output;                                      /* output block */
                    162: unsigned int *outputLen;                          /* length of output block */
                    163: unsigned char *input;                                        /* input block */
                    164: unsigned int inputLen;                             /* length of input block */
                    165: R_RSA_PRIVATE_KEY *privateKey;                           /* RSA private key */
                    166: {
                    167:   int status;
                    168:   unsigned char pkcsBlock[MAX_RSA_MODULUS_LEN];
                    169:   unsigned int i, modulusLen, pkcsBlockLen;
                    170:   
                    171:   modulusLen = (privateKey->bits + 7) / 8;
                    172:   if (inputLen > modulusLen)
                    173:     return (RE_LEN);
                    174:   
                    175:   if (status = RSAPrivateBlock
                    176:       (pkcsBlock, &pkcsBlockLen, input, inputLen, privateKey))
                    177:     return (status);
                    178:   
                    179:   if (pkcsBlockLen != modulusLen)
                    180:     return (RE_LEN);
                    181:   
                    182:   /* Require block type 2.
                    183:    */
                    184:   if ((pkcsBlock[0] != 0) || (pkcsBlock[1] != 2))
                    185:    return (RE_DATA);
                    186: 
                    187:   for (i = 2; i < modulusLen-1; i++)
                    188:     /* separator */
                    189:     if (pkcsBlock[i] == 0)
                    190:       break;
                    191:     
                    192:   i++;
                    193:   if (i >= modulusLen)
                    194:     return (RE_DATA);
                    195:     
                    196:   *outputLen = modulusLen - i;
                    197:   
                    198:   if (*outputLen + 11 > modulusLen)
                    199:     return (RE_DATA);
                    200: 
                    201:   R_memcpy ((POINTER)output, (POINTER)&pkcsBlock[i], *outputLen);
                    202:   
                    203:   /* Zeroize sensitive information.
                    204:    */
                    205:   R_memset ((POINTER)pkcsBlock, 0, sizeof (pkcsBlock));
                    206:   
                    207:   return (0);
                    208: }
                    209: 
                    210: /* Raw RSA public-key operation. Output has same length as modulus.
                    211: 
                    212:    Assumes inputLen < length of modulus.
                    213:    Requires input < modulus.
                    214:  */
                    215: static int RSAPublicBlock (output, outputLen, input, inputLen, publicKey)
                    216: unsigned char *output;                                      /* output block */
                    217: unsigned int *outputLen;                          /* length of output block */
                    218: unsigned char *input;                                        /* input block */
                    219: unsigned int inputLen;                             /* length of input block */
                    220: R_RSA_PUBLIC_KEY *publicKey;                              /* RSA public key */
                    221: {
                    222:   NN_DIGIT c[MAX_NN_DIGITS], e[MAX_NN_DIGITS], m[MAX_NN_DIGITS],
                    223:     n[MAX_NN_DIGITS];
                    224:   unsigned int eDigits, nDigits;
                    225: 
                    226:   NN_Decode (m, MAX_NN_DIGITS, input, inputLen);
                    227:   NN_Decode (n, MAX_NN_DIGITS, publicKey->modulus, MAX_RSA_MODULUS_LEN);
                    228:   NN_Decode (e, MAX_NN_DIGITS, publicKey->exponent, MAX_RSA_MODULUS_LEN);
                    229:   nDigits = NN_Digits (n, MAX_NN_DIGITS);
                    230:   eDigits = NN_Digits (e, MAX_NN_DIGITS);
                    231:   
                    232:   if (NN_Cmp (m, n, nDigits) >= 0)
                    233:     return (RE_DATA);
                    234:   
                    235:   /* Compute c = m^e mod n.
                    236:    */
                    237:   NN_ModExp (c, m, e, eDigits, n, nDigits);
                    238: 
                    239:   *outputLen = (publicKey->bits + 7) / 8;
                    240:   NN_Encode (output, *outputLen, c, nDigits);
                    241:   
                    242:   /* Zeroize sensitive information.
                    243:    */
                    244:   R_memset ((POINTER)c, 0, sizeof (c));
                    245:   R_memset ((POINTER)m, 0, sizeof (m));
                    246: 
                    247:   return (0);
                    248: }
                    249: 
                    250: /* Raw RSA private-key operation. Output has same length as modulus.
                    251: 
                    252:    Assumes inputLen < length of modulus.
                    253:    Requires input < modulus.
                    254:  */
                    255: static int RSAPrivateBlock (output, outputLen, input, inputLen, privateKey)
                    256: unsigned char *output;                                      /* output block */
                    257: unsigned int *outputLen;                          /* length of output block */
                    258: unsigned char *input;                                        /* input block */
                    259: unsigned int inputLen;                             /* length of input block */
                    260: R_RSA_PRIVATE_KEY *privateKey;                           /* RSA private key */
                    261: {
                    262:   NN_DIGIT c[MAX_NN_DIGITS], cP[MAX_NN_DIGITS], cQ[MAX_NN_DIGITS],
                    263:     dP[MAX_NN_DIGITS], dQ[MAX_NN_DIGITS], mP[MAX_NN_DIGITS],
                    264:     mQ[MAX_NN_DIGITS], n[MAX_NN_DIGITS], p[MAX_NN_DIGITS], q[MAX_NN_DIGITS],
                    265:     qInv[MAX_NN_DIGITS], t[MAX_NN_DIGITS];
                    266:   unsigned int cDigits, nDigits, pDigits;
                    267:   
                    268:   NN_Decode (c, MAX_NN_DIGITS, input, inputLen);
                    269:   NN_Decode (n, MAX_NN_DIGITS, privateKey->modulus, MAX_RSA_MODULUS_LEN);
                    270:   NN_Decode (p, MAX_NN_DIGITS, privateKey->prime[0], MAX_RSA_PRIME_LEN);
                    271:   NN_Decode (q, MAX_NN_DIGITS, privateKey->prime[1], MAX_RSA_PRIME_LEN);
                    272:   NN_Decode 
                    273:     (dP, MAX_NN_DIGITS, privateKey->primeExponent[0], MAX_RSA_PRIME_LEN);
                    274:   NN_Decode 
                    275:     (dQ, MAX_NN_DIGITS, privateKey->primeExponent[1], MAX_RSA_PRIME_LEN);
                    276:   NN_Decode (qInv, MAX_NN_DIGITS, privateKey->coefficient, MAX_RSA_PRIME_LEN);
                    277:   cDigits = NN_Digits (c, MAX_NN_DIGITS);
                    278:   nDigits = NN_Digits (n, MAX_NN_DIGITS);
                    279:   pDigits = NN_Digits (p, MAX_NN_DIGITS);
                    280: 
                    281:   if (NN_Cmp (c, n, nDigits) >= 0)
                    282:     return (RE_DATA);
                    283:   
                    284:   /* Compute mP = cP^dP mod p  and  mQ = cQ^dQ mod q. (Assumes q has
                    285:      length at most pDigits, i.e., p > q.)
                    286:    */
                    287:   NN_Mod (cP, c, cDigits, p, pDigits);
                    288:   NN_Mod (cQ, c, cDigits, q, pDigits);
                    289:   NN_ModExp (mP, cP, dP, pDigits, p, pDigits);
                    290:   NN_AssignZero (mQ, nDigits);
                    291:   NN_ModExp (mQ, cQ, dQ, pDigits, q, pDigits);
                    292:   
                    293:   /* Chinese Remainder Theorem:
                    294:        m = ((((mP - mQ) mod p) * qInv) mod p) * q + mQ.
                    295:    */
                    296:   if (NN_Cmp (mP, mQ, pDigits) >= 0)
                    297:     NN_Sub (t, mP, mQ, pDigits);
                    298:   else {
                    299:     NN_Sub (t, mQ, mP, pDigits);
                    300:     NN_Sub (t, p, t, pDigits);
                    301:   }
                    302:   NN_ModMult (t, t, qInv, p, pDigits);
                    303:   NN_Mult (t, t, q, pDigits);
                    304:   NN_Add (t, t, mQ, nDigits);
                    305: 
                    306:   *outputLen = (privateKey->bits + 7) / 8;
                    307:   NN_Encode (output, *outputLen, t, nDigits);
                    308: 
                    309:   /* Zeroize sensitive information.
                    310:    */
                    311:   R_memset ((POINTER)c, 0, sizeof (c));
                    312:   R_memset ((POINTER)cP, 0, sizeof (cP));
                    313:   R_memset ((POINTER)cQ, 0, sizeof (cQ));
                    314:   R_memset ((POINTER)dP, 0, sizeof (dP));
                    315:   R_memset ((POINTER)dQ, 0, sizeof (dQ));
                    316:   R_memset ((POINTER)mP, 0, sizeof (mP));
                    317:   R_memset ((POINTER)mQ, 0, sizeof (mQ));
                    318:   R_memset ((POINTER)p, 0, sizeof (p));
                    319:   R_memset ((POINTER)q, 0, sizeof (q));
                    320:   R_memset ((POINTER)qInv, 0, sizeof (qInv));
                    321:   R_memset ((POINTER)t, 0, sizeof (t));
                    322: 
                    323:   return (0);
                    324: }

unix.superglobalmegacorp.com

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