|
|
1.1 ! root 1: /* R_KEYGEN.C - key-pair generation 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 "nn.h" ! 12: #include "prime.h" ! 13: ! 14: static int GenerateDigits PROTO_LIST ! 15: ((NN_DIGIT *, unsigned int, R_RANDOM_STRUCT *)); ! 16: ! 17: /* Generates an RSA key pair with a given length and public exponent. ! 18: */ ! 19: int R_GeneratePEMKeys (publicKey, privateKey, protoKey, randomStruct) ! 20: R_RSA_PUBLIC_KEY *publicKey; /* new RSA public key */ ! 21: R_RSA_PRIVATE_KEY *privateKey; /* new RSA private key */ ! 22: R_RSA_PROTO_KEY *protoKey; /* RSA prototype key */ ! 23: R_RANDOM_STRUCT *randomStruct; /* random structure */ ! 24: { ! 25: NN_DIGIT d[MAX_NN_DIGITS], dP[MAX_NN_DIGITS], dQ[MAX_NN_DIGITS], ! 26: e[MAX_NN_DIGITS], n[MAX_NN_DIGITS], p[MAX_NN_DIGITS], phiN[MAX_NN_DIGITS], ! 27: pMinus1[MAX_NN_DIGITS], q[MAX_NN_DIGITS], qInv[MAX_NN_DIGITS], ! 28: qMinus1[MAX_NN_DIGITS], t[MAX_NN_DIGITS]; ! 29: int status; ! 30: unsigned int nDigits, pDigits; ! 31: ! 32: if ((protoKey->bits < MIN_RSA_MODULUS_BITS) || ! 33: (protoKey->bits > MAX_RSA_MODULUS_BITS)) ! 34: return (RE_MODULUS_LEN); ! 35: nDigits = (protoKey->bits + NN_DIGIT_BITS - 1) / NN_DIGIT_BITS; ! 36: pDigits = (nDigits + 1) / 2; ! 37: ! 38: /* Generate random RSA primes p and q so that product has correct length. ! 39: */ ! 40: if ((status = GenerateDigits (p, pDigits, randomStruct)) || ! 41: (status = GenerateDigits (q, pDigits, randomStruct))) ! 42: return (status); ! 43: ! 44: /* NOTE: for 65537, this assumes NN_DIGIT is at least 17 bits. */ ! 45: NN_ASSIGN_DIGIT ! 46: (e, protoKey->useFermat4 ? (NN_DIGIT)65537 : (NN_DIGIT)3, nDigits); ! 47: FindRSAPrime (p, (protoKey->bits + 1) / 2, p, pDigits, e, 1); ! 48: FindRSAPrime (q, protoKey->bits / 2, q, pDigits, e, 1); ! 49: ! 50: /* Sort so that p > q. (p = q case is extremely unlikely.) ! 51: */ ! 52: if (NN_Cmp (p, q, pDigits) < 0) { ! 53: NN_Assign (t, p, pDigits); ! 54: NN_Assign (p, q, pDigits); ! 55: NN_Assign (q, t, pDigits); ! 56: } ! 57: ! 58: /* Compute n = pq, qInv = q^{-1} mod p, d = e^{-1} mod (p-1)(q-1), ! 59: dP = d mod p-1, dQ = d mod q-1. ! 60: */ ! 61: NN_Mult (n, p, q, pDigits); ! 62: NN_ModInv (qInv, q, p, pDigits); ! 63: ! 64: NN_ASSIGN_DIGIT (t, 1, pDigits); ! 65: NN_Sub (pMinus1, p, t, pDigits); ! 66: NN_Sub (qMinus1, q, t, pDigits); ! 67: NN_Mult (phiN, pMinus1, qMinus1, pDigits); ! 68: ! 69: NN_ModInv (d, e, phiN, nDigits); ! 70: NN_Mod (dP, d, nDigits, pMinus1, pDigits); ! 71: NN_Mod (dQ, d, nDigits, qMinus1, pDigits); ! 72: ! 73: publicKey->bits = privateKey->bits = protoKey->bits; ! 74: NN_Encode (publicKey->modulus, MAX_RSA_MODULUS_LEN, n, nDigits); ! 75: NN_Encode (publicKey->exponent, MAX_RSA_MODULUS_LEN, e, 1); ! 76: R_memcpy ! 77: ((POINTER)privateKey->modulus, (POINTER)publicKey->modulus, ! 78: MAX_RSA_MODULUS_LEN); ! 79: R_memcpy ! 80: ((POINTER)privateKey->publicExponent, (POINTER)publicKey->exponent, ! 81: MAX_RSA_MODULUS_LEN); ! 82: NN_Encode (privateKey->exponent, MAX_RSA_MODULUS_LEN, d, nDigits); ! 83: NN_Encode (privateKey->prime[0], MAX_RSA_PRIME_LEN, p, pDigits); ! 84: NN_Encode (privateKey->prime[1], MAX_RSA_PRIME_LEN, q, pDigits); ! 85: NN_Encode (privateKey->primeExponent[0], MAX_RSA_PRIME_LEN, dP, pDigits); ! 86: NN_Encode (privateKey->primeExponent[1], MAX_RSA_PRIME_LEN, dQ, pDigits); ! 87: NN_Encode (privateKey->coefficient, MAX_RSA_PRIME_LEN, qInv, pDigits); ! 88: ! 89: /* Zeroize sensitive information. ! 90: */ ! 91: R_memset ((POINTER)d, 0, sizeof (d)); ! 92: R_memset ((POINTER)dP, 0, sizeof (dP)); ! 93: R_memset ((POINTER)dQ, 0, sizeof (dQ)); ! 94: R_memset ((POINTER)p, 0, sizeof (p)); ! 95: R_memset ((POINTER)phiN, 0, sizeof (phiN)); ! 96: R_memset ((POINTER)pMinus1, 0, sizeof (pMinus1)); ! 97: R_memset ((POINTER)q, 0, sizeof (q)); ! 98: R_memset ((POINTER)qInv, 0, sizeof (qInv)); ! 99: R_memset ((POINTER)qMinus1, 0, sizeof (qMinus1)); ! 100: R_memset ((POINTER)t, 0, sizeof (t)); ! 101: ! 102: return (0); ! 103: } ! 104: ! 105: static int GenerateDigits (a, digits, randomStruct) ! 106: NN_DIGIT *a; ! 107: R_RANDOM_STRUCT *randomStruct; ! 108: unsigned int digits; ! 109: { ! 110: int status; ! 111: unsigned char t[MAX_RSA_MODULUS_LEN]; ! 112: ! 113: if (status = R_GenerateBytes (t, digits * NN_DIGIT_LEN, randomStruct)) ! 114: return (status); ! 115: NN_Decode (a, digits, t, digits * NN_DIGIT_LEN); ! 116: ! 117: /* Zeroize sensitive information. ! 118: */ ! 119: R_memset ((POINTER)t, 0, sizeof (t)); ! 120: ! 121: return (0); ! 122: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.