|
|
1.1 ! root 1: /* R_DH.C - Diffie-Hellman routines for RSAREF ! 2: */ ! 3: ! 4: /* Copyright (C) RSA Laboratories, a division of RSA Data Security, ! 5: Inc., created 1993. 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: /* Generates Diffie-Hellman parameters. ! 15: */ ! 16: int R_GenerateDHParams (params, primeBits, subPrimeBits, randomStruct) ! 17: R_DH_PARAMS *params; /* new Diffie-Hellman parameters */ ! 18: unsigned int primeBits; /* length of prime in bits */ ! 19: unsigned int subPrimeBits; /* length of subprime in bits */ ! 20: R_RANDOM_STRUCT *randomStruct; /* random structure */ ! 21: { ! 22: int status; ! 23: NN_DIGIT g[MAX_NN_DIGITS], p[MAX_NN_DIGITS], q[MAX_NN_DIGITS], ! 24: t[MAX_NN_DIGITS], u[MAX_NN_DIGITS], v[MAX_NN_DIGITS]; ! 25: unsigned int pDigits; ! 26: ! 27: pDigits = (primeBits + NN_DIGIT_BITS - 1) / NN_DIGIT_BITS; ! 28: ! 29: /* Generate subprime q between 2^(subPrimeBits-1) and ! 30: 2^subPrimeBits-1, searching in steps of 2. ! 31: */ ! 32: NN_Assign2Exp (t, subPrimeBits-1, pDigits); ! 33: NN_Assign (u, t, pDigits); ! 34: NN_ASSIGN_DIGIT (v, 1, pDigits); ! 35: NN_Sub (v, t, v, pDigits); ! 36: NN_Add (u, u, v, pDigits); ! 37: NN_ASSIGN_DIGIT (v, 2, pDigits); ! 38: if (status = GeneratePrime (q, t, u, v, pDigits, randomStruct)) ! 39: return (status); ! 40: ! 41: /* Generate prime p between 2^(primeBits-1) and 2^primeBits-1, ! 42: searching in steps of 2*q. ! 43: */ ! 44: NN_Assign2Exp (t, primeBits-1, pDigits); ! 45: NN_Assign (u, t, pDigits); ! 46: NN_ASSIGN_DIGIT (v, 1, pDigits); ! 47: NN_Sub (v, t, v, pDigits); ! 48: NN_Add (u, u, v, pDigits); ! 49: NN_LShift (v, q, 1, pDigits); ! 50: if (status = GeneratePrime (p, t, u, v, pDigits, randomStruct)) ! 51: return (status); ! 52: ! 53: /* Generate generator g for subgroup as 2^((p-1)/q) mod p. ! 54: */ ! 55: NN_ASSIGN_DIGIT (g, 2, pDigits); ! 56: NN_Div (t, u, p, pDigits, q, pDigits); ! 57: NN_ModExp (g, g, t, pDigits, p, pDigits); ! 58: ! 59: params->generatorLen = params->primeLen = DH_PRIME_LEN (primeBits); ! 60: NN_Encode (params->prime, params->primeLen, p, pDigits); ! 61: NN_Encode (params->generator, params->generatorLen, g, pDigits); ! 62: ! 63: return (0); ! 64: } ! 65: ! 66: /* Sets up Diffie-Hellman key agreement. Public value has same length ! 67: as prime. ! 68: */ ! 69: int R_SetupDHAgreement ! 70: (publicValue, privateValue, privateValueLen, params, randomStruct) ! 71: unsigned char *publicValue; /* new public value */ ! 72: unsigned char *privateValue; /* new private value */ ! 73: unsigned int privateValueLen; /* length of private value */ ! 74: R_DH_PARAMS *params; /* Diffie-Hellman parameters */ ! 75: R_RANDOM_STRUCT *randomStruct; /* random structure */ ! 76: { ! 77: int status; ! 78: NN_DIGIT g[MAX_NN_DIGITS], p[MAX_NN_DIGITS], x[MAX_NN_DIGITS], ! 79: y[MAX_NN_DIGITS]; ! 80: unsigned int pDigits, xDigits; ! 81: ! 82: NN_Decode (p, MAX_NN_DIGITS, params->prime, params->primeLen); ! 83: pDigits = NN_Digits (p, MAX_NN_DIGITS); ! 84: NN_Decode (g, pDigits, params->generator, params->generatorLen); ! 85: ! 86: /* Generate private value. ! 87: */ ! 88: if (status = R_GenerateBytes (privateValue, privateValueLen, randomStruct)) ! 89: return (status); ! 90: NN_Decode (x, pDigits, privateValue, privateValueLen); ! 91: xDigits = NN_Digits (x, pDigits); ! 92: ! 93: /* Compute y = g^x mod p. ! 94: */ ! 95: NN_ModExp (y, g, x, xDigits, p, pDigits); ! 96: ! 97: NN_Encode (publicValue, params->primeLen, y, pDigits); ! 98: ! 99: /* Zeroize sensitive information. ! 100: */ ! 101: R_memset ((POINTER)x, 0, sizeof (x)); ! 102: ! 103: return (0); ! 104: } ! 105: ! 106: /* Computes agreed key from the other party's public value, a private ! 107: value, and Diffie-Hellman parameters. Other public value and ! 108: agreed-upon key have same length as prime. ! 109: ! 110: Requires otherPublicValue < prime. ! 111: */ ! 112: int R_ComputeDHAgreedKey ! 113: (agreedKey, otherPublicValue, privateValue, privateValueLen, params) ! 114: unsigned char *agreedKey; /* new agreed key */ ! 115: unsigned char *otherPublicValue; /* other's public value */ ! 116: unsigned char *privateValue; /* private value */ ! 117: unsigned int privateValueLen; /* length of private value */ ! 118: R_DH_PARAMS *params; /* Diffie-Hellman parameters */ ! 119: { ! 120: NN_DIGIT p[MAX_NN_DIGITS], x[MAX_NN_DIGITS], y[MAX_NN_DIGITS], ! 121: z[MAX_NN_DIGITS]; ! 122: unsigned int pDigits, xDigits; ! 123: ! 124: NN_Decode (p, MAX_NN_DIGITS, params->prime, params->primeLen); ! 125: pDigits = NN_Digits (p, MAX_NN_DIGITS); ! 126: NN_Decode (x, pDigits, privateValue, privateValueLen); ! 127: xDigits = NN_Digits (x, pDigits); ! 128: NN_Decode (y, pDigits, otherPublicValue, params->primeLen); ! 129: ! 130: if (NN_Cmp (y, p, pDigits) >= 0) ! 131: return (RE_DATA); ! 132: ! 133: /* Compute z = y^x mod p. ! 134: */ ! 135: NN_ModExp (z, y, x, xDigits, p, pDigits); ! 136: ! 137: NN_Encode (agreedKey, params->primeLen, z, pDigits); ! 138: ! 139: /* Zeroize sensitive information. ! 140: */ ! 141: R_memset ((POINTER)x, 0, sizeof (x)); ! 142: R_memset ((POINTER)z, 0, sizeof (z)); ! 143: ! 144: return (0); ! 145: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.