Annotation of rsaref/source/rsa.c, revision 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.