void DH_SecretKey_Generate ( IN UINT8 PublicKey[], IN UINT PublicKeyLength, IN UINT8 PValue[], IN UINT PValueLength, IN UINT8 PrivateKey[], IN UINT PrivateKeyLength, OUT UINT8 SecretKey[], INOUT UINT *SecretKeyLength) { PBIG_INTEGER pBI_P = NULL; PBIG_INTEGER pBI_SecretKey = NULL; PBIG_INTEGER pBI_PrivateKey = NULL; PBIG_INTEGER pBI_PublicKey = NULL; if (PublicKeyLength == 0) { DBGPRINT(RT_DEBUG_ERROR, ("DH_SecretKey_Generate: public key length is (%d)\n", PublicKeyLength)); return; } if (PValueLength == 0) { DBGPRINT(RT_DEBUG_ERROR, ("DH_SecretKey_Generate: P length is (%d)\n", PValueLength)); return; } if (PrivateKeyLength == 0) { DBGPRINT(RT_DEBUG_ERROR, ("DH_SecretKey_Generate: private key length is (%d)\n", PrivateKeyLength)); return; } if (*SecretKeyLength < PValueLength) { DBGPRINT(RT_DEBUG_ERROR, ("DH_SecretKey_Generate: secret key length(%d) must be large or equal than P length(%d)\n", *SecretKeyLength, PValueLength)); return; } if (!(PValue[PValueLength - 1] & 0x1)) { DBGPRINT(RT_DEBUG_ERROR, ("DH_SecretKey_Generate: P value must be odd\n")); return; } BigInteger_Init(&pBI_P); BigInteger_Init(&pBI_PrivateKey); BigInteger_Init(&pBI_PublicKey); BigInteger_Init(&pBI_SecretKey); BigInteger_Bin2BI(PublicKey, PublicKeyLength, &pBI_PublicKey); BigInteger_Bin2BI(PValue, PValueLength, &pBI_P); BigInteger_Bin2BI(PrivateKey, PrivateKeyLength, &pBI_PrivateKey); BigInteger_Montgomery_ExpMod(pBI_PublicKey, pBI_PrivateKey, pBI_P, &pBI_SecretKey); BigInteger_BI2Bin(pBI_SecretKey, SecretKey, SecretKeyLength); BigInteger_Free(&pBI_P); BigInteger_Free(&pBI_PrivateKey); BigInteger_Free(&pBI_PublicKey); BigInteger_Free(&pBI_SecretKey); }
VOID BigInteger_AllocSize ( IN PBIG_INTEGER *pBI, IN INT Length) { UINT ArrayLength = 0; if (Length <= 0) return; if (*pBI == NULL) BigInteger_Init(pBI); /* Caculate array size */ ArrayLength = Length >> 0x2; if ((Length & 0x3) != 0) ArrayLength++; if (((*pBI)->pIntegerArray != NULL) && ((*pBI)->AllocSize < (sizeof(UINT32)*ArrayLength))) BigInteger_Free_AllocSize(pBI); if ((*pBI)->pIntegerArray == NULL) { os_alloc_mem(NULL, (UCHAR **)&((*pBI)->pIntegerArray), sizeof(UINT32)*ArrayLength); // if (((*pBI)->pIntegerArray = (UINT32 *) kmalloc(sizeof(UINT32)*ArrayLength, GFP_ATOMIC)) == NULL) { if ((*pBI)->pIntegerArray == NULL) { DEBUGPRINT("BigInteger_AllocSize: allocate %d bytes memory failure.\n", (sizeof(UINT32)*ArrayLength)); return; } /* End of if */ (*pBI)->AllocSize = sizeof(UINT32)*ArrayLength; } /* End of if */ NdisZeroMemory((*pBI)->pIntegerArray, (*pBI)->AllocSize); (*pBI)->ArrayLength = ArrayLength; (*pBI)->IntegerLength = Length; } /* End of BigInteger_AllocSize */
/* ======================================================================== Routine Description: Diffie-Hellman public key generation Arguments: GValue Array in UINT8 GValueLength The length of G in bytes PValue Array in UINT8 PValueLength The length of P in bytes PrivateKey Private key PrivateKeyLength The length of Private key in bytes Return Value: PublicKey Public key PublicKeyLength The length of public key in bytes Note: Reference to RFC2631 PublicKey = G^PrivateKey (mod P) ======================================================================== */ void DH_PublicKey_Generate ( IN UINT8 GValue[], IN UINT GValueLength, IN UINT8 PValue[], IN UINT PValueLength, IN UINT8 PrivateKey[], IN UINT PrivateKeyLength, OUT UINT8 PublicKey[], INOUT UINT *PublicKeyLength) { PBIG_INTEGER pBI_G = NULL; PBIG_INTEGER pBI_P = NULL; PBIG_INTEGER pBI_PrivateKey = NULL; PBIG_INTEGER pBI_PublicKey = NULL; /* * 1. Check the input parameters * - GValueLength, PValueLength and PrivateLength must be large than zero * - PublicKeyLength must be large or equal than PValueLength * - PValue must be odd * * - PValue must be prime number (no implement) * - GValue must be greater than 0 but less than the PValue (no implement) */ if (GValueLength == 0) { DBGPRINT(RT_DEBUG_ERROR, ("DH_PublicKey_Generate: G length is (%d)\n", GValueLength)); return; } /* End of if */ if (PValueLength == 0) { DBGPRINT(RT_DEBUG_ERROR, ("DH_PublicKey_Generate: P length is (%d)\n", PValueLength)); return; } /* End of if */ if (PrivateKeyLength == 0) { DBGPRINT(RT_DEBUG_ERROR, ("DH_PublicKey_Generate: private key length is (%d)\n", PrivateKeyLength)); return; } /* End of if */ if (*PublicKeyLength < PValueLength) { DBGPRINT(RT_DEBUG_ERROR, ("DH_PublicKey_Generate: public key length(%d) must be large or equal than P length(%d)\n", *PublicKeyLength, PValueLength)); return; } /* End of if */ if (!(PValue[PValueLength - 1] & 0x1)) { DBGPRINT(RT_DEBUG_ERROR, ("DH_PublicKey_Generate: P value must be odd\n")); return; } /* End of if */ /* * 2. Transfer parameters to BigInteger structure */ BigInteger_Init(&pBI_G); BigInteger_Init(&pBI_P); BigInteger_Init(&pBI_PrivateKey); BigInteger_Init(&pBI_PublicKey); BigInteger_Bin2BI(GValue, GValueLength, &pBI_G); BigInteger_Bin2BI(PValue, PValueLength, &pBI_P); BigInteger_Bin2BI(PrivateKey, PrivateKeyLength, &pBI_PrivateKey); /* * 3. Calculate PublicKey = G^PrivateKey (mod P) * - BigInteger Operation * - Montgomery reduction */ BigInteger_Montgomery_ExpMod(pBI_G, pBI_PrivateKey, pBI_P, &pBI_PublicKey); /* * 4. Transfer BigInteger structure to char array */ BigInteger_BI2Bin(pBI_PublicKey, PublicKey, PublicKeyLength); BigInteger_Free(&pBI_G); BigInteger_Free(&pBI_P); BigInteger_Free(&pBI_PrivateKey); BigInteger_Free(&pBI_PublicKey); } /* End of DH_PublicKey_Generate */