|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.